Implementing Multitenancy Using Namespaces

The Namespaces API allows you to easily enable multitenancy in your application, simply by selecting a namespace string for each tenant in web.xml using the NamespaceManager package.

Setting the current namespace

You can get, set, and validate namespaces using NamespaceManager. The namespace manager allows you to set a current namespace for namespace-enabled APIs. You set a current namespace up-front using web.xml, and the datastore and memcache automatically use that namespace.

Most App Engine developers will use their Google Apps domain as the current namespace. Google Apps lets you deploy your app to any domain that you own, so you can easily use this mechanism to configure different namespaces for different domains. Then, you can use those separate namespaces to segregate data across the domains. For more information about setting multiple domains in the Google Apps dashboard, see Deploying Your Application on Your Google Apps URL.

The following code sample shows you how to set the current namespace to the Google Apps domain that was used to map the URL. Notably, this string will be the same for all URLs mapped via the same Google Apps domain.

You can set namespaces in Java using the servlet Filter interface before invoking servlet methods. The following simple example demonstrates how to use your Google Apps domain as the current namespace:

// Filter to set the Google Apps domain as the namespace.
public class NamespaceFilter implements Filter {
  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
      throws IOException, ServletException {
    // Make sure set() is only called if the current namespace is not already set.
    if (NamespaceManager.get() == null) {
      // If your app is hosted on appspot, this will be empty. Otherwise it will be the domain
      // the app is hosted on.
    chain.doFilter(req, res); // Pass request back down the filter chain

The namespace filter must be configured in the web.xml file. Note that, if there are multiple filter entries, the first namespace to be set is the one that will be used.

The following code sample demonstrates how to configure the namespace filter in web.xml:

<!-- Configure the namespace filter. -->


For more general information on the web.xml file and mapping URL paths to servlets, refer to The Deployment Descriptor: web.xml.

You can also set a new namespace for a temporary operation, resetting the original namespace once the operation is complete, using the try/finally pattern shown below:

// Set the namepace temporarily to "abc"
    String oldNamespace = NamespaceManager.get();
    try {
//      ... perform operation using current namespace ...
    } finally {

If you do not specify a value for namespace, the namespace is set to an empty string. The namespace string is arbitrary, but also limited to a maximum of 100 alphanumeric characters, periods, underscores, and hyphens. More explicitly, namespace strings must match the regular expression [0-9A-Za-z._-]{0,100}.

By convention, all namespaces starting with "_" (underscore) are reserved for system use. This system namespace rule is not enforced, but you could easily encounter undefined negative consequences if you do not follow it.

Avoiding data leaks

One of the risks commonly associated with multitenant apps is the danger that data will leak across namespaces. Unintended data leaks can arise from many sources, including:

  • Using namespaces with App Engine APIs that do not yet support namespaces. For example, Blobstore does not support namespaces. If you use Namespaces with Blobstore, you need to avoid using Blobstore queries for end user requests, or Blobstore keys from untrusted sources.
  • Using an external storage medium (instead of memcache and datastore), via URL Fetch or some other mechanism, without providing a compartmentalization scheme for namespaces.
  • Setting a namespace based on a user's email domain. In most cases, you don't want all email addresses of a domain to access a namespace. Using the email domain also prevents your application from using a namespace until the user is logged in.

Deploying namespaces

The following sections describe how to deploy namespaces with other App Engine tools and APIs.

Creating namespaces on a per user basis

Some applications need to create namespaces on a per-user basis. If you want to compartmentalize data at the user level for logged-in users, consider using User.getUserId(), which returns a unique, permanent ID for the user. The following code sample demonstrates how to use the Users API for this purpose:

if ( == null) {
  // Assuming there is a logged in user.
  namespace = UserServiceFactory.getUserService().getCurrentUser().getUserId();

Typically, apps that create namespaces on a per-user basis also provide specific landing pages to different users. In these cases, the application needs to provide a URL scheme dictating which landing page to display to a user.

Using namespaces with the Datastore

By default, the datastore uses the current namespace setting in the namespace manager for datastore requests. The API applies this current namespace to Key or Query objects when they are created. Therefore, you need to be careful if an application stores Key or Query objects in serialized forms, since the namespace is preserved in those serializations.

If you are using deserialized Key and Query objects, make sure that they behave as intended. Most simple applications that use datastore (put/query/get) without using other storage mechanisms will work as expected by setting the current namespace before calling any datastore API.

Query and Key objects demonstrate the following, unique behaviors with regard to namespaces:

  • Query and Key objects inherit the current namespace when constructed, unless you set an explicit namespace.
  • When an application creates a new Key from an ancestor, the new Key inherits the namespace of the ancestor.
  • There is no API for Java to explicitly set the namespace of a Key or Query.
The following code example shows the SomeRequest request handler for incrementing the count for the current namespace and the arbitrarily named -global- namespace in a Counter datastore entity.
public class UpdateCountsServlet extends HttpServlet {
  private static final int NUM_RETRIES = 10;

  @Entity public class CounterPojo {
    @Id public Long id;
    @Index public String name;
    public Long count;

    public CounterPojo() {
      this.count = 0L;

    public CounterPojo(String name) { = name;
      this.count = 0L;

    public void increment() {

  // Increment the count in a Counter datastore entity.
  public long updateCount(String countName) {

    CounterPojo cp = ofy().load().type(CounterPojo.class).filter("name", countName).first().now();
    if (cp == null) {
      cp = new CounterPojo(countName);

    return cp.count;

  protected void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws {

    // Update the count for the current namespace.

    // Update the count for the "-global-" namespace.
    String namespace = NamespaceManager.get();
    try {
      // "-global-" is namespace reserved by the application.
    } finally {
    resp.getWriter().println("Counts are now updated.");

Using namespaces with the Memcache

By default, memcache uses the current namespace from the namespace manager for memcache requests. In most cases, you do not need to explicitly set a namespace in the memcach