Co-authored with Bing Huan Chio, Software Engineer, Halo.

With ​over 65 million units sold, Halo is one of the most popular game franchises of all time. In order to support social multi-player gaming in the latest game in its series, Halo 5: Guardians (released 10/27/2015), the Halo development team implemented the Halo: Spartan Companies platform. In order to handle the scalability needs of their data-tier, and to support iterative rapid development of new features, they chose Azure Cosmos DB.

Halo 5: Guardians is a first-person shooting game on the Xbox, which supports both single and multi-player gaming. In multi-player gaming, a popular feature is the ability to create and join groups or Companies with your friends, or with other like-minded Halo players for competitive and well-matched games. Spartan Companies was launched in order to make it easy to create companies within Halo, easily integrate those user-created companies with social media like Twitter and Facebook, track your badges and stats, and manage company memberships.

Why Azure Cosmos DB?

The Halo development team had three major kinds of entities to store: companies, company memberships, and company invites. Each company had to track the Company ID (an internal guide), the display name, a number of optional social media handles (Twitter, Facebook, Twitch.TV and YouTube), the status of the company, the motto, awarded badges (which could be zero to many), favorite games (again zero to many), and creation time.

A number of operations had to be supported at scale against company metadata:

Real-time query and discovery of companies through multiple attributes (display name, social media handles, memberships)

Updating the companies with achievements and stats during gameplay, and customizations from the halowaypoint.com portal

Updating the status of a company based on certain rules (from Inactive to Active)

Within each company, the database had to support efficient operations against invites or join requests for that specific company:

Store data about invites to join/invite a company, including the expiration time for an invite

Update the status of an invite from Pending to Accepted or Declined

Perform lookups against Invite Id, Inviter Id, Company Id, and combinations of status, invite type and these identifiers

The Halo development team considered various NoSQL technologies for their data platform, but ultimately chose Azure Cosmos DB due to the speed and flexibility offered by its automatic indexing capabilities. Cosmos DB allowed the Halo: Spartan Companies’ services to support queries without having to setup and maintain schema or secondary indexes.

The partitioning strategy for the Halo company memberships and invites followed a similar design described in the Next Games Walking Dead: No Man's Land case study, using hash partitioning on company ID. The Halo team also used the following design patterns to implement their business rules for companies within their Cosmos DB collections.

Composite ID properties for "point reads": In Cosmos DB, "point reads" using the ID property and ReadDocumentAsync are performant with the release of ID based routing. Reads of 1KB documents complete under 1 ms (excluding network latency), and consume only 1 request unit (unit) allowing for a high volume of parallel requests. The Halo team implemented a composite ID property concatenated from the (InviteType, InviteID, InviterID) for their invite documents to take advantage of the performance gains from ID lookups.

In Cosmos DB, "point reads" using the ID property and ReadDocumentAsync are performant with the release of ID based routing. Reads of 1KB documents complete under 1 ms (excluding network latency), and consume only 1 request unit (unit) allowing for a high volume of parallel requests. The Halo team implemented a composite ID property concatenated from the (InviteType, InviteID, InviterID) for their invite documents to take advantage of the performance gains from ID lookups. Triggers for uniqueness against non-ID properties: The Halo team required that both the Company ID and the Display Name be globally unique. In order to support this, they stored company specific metadata (which could fit within a single collection) and used Cosmos DB triggers to enforce uniqueness. Since Cosmos DB supports transactions over the scope of a collection, every write of a company document used a post-trigger to query for other companies with the same name and rollback the update if one was found. This would get surfaced as an error to their users to pick a different name. To test out the transactional support available in Cosmos DB, you can run the samples on GitHub or read the documentation.

The Halo team required that both the Company ID and the Display Name be globally unique. In order to support this, they stored company specific metadata (which could fit within a single collection) and used Cosmos DB triggers to enforce uniqueness. Since Cosmos DB supports transactions over the scope of a collection, every write of a company document used a post-trigger to query for other companies with the same name and rollback the update if one was found. This would get surfaced as an error to their users to pick a different name. To test out the transactional support available in Cosmos DB, you can run the samples on GitHub or read the documentation. Representing non-native JSON types: The data model for companies and company invites used DateTimes in multiple places. In order to support efficient storage, filtering and sorting against dates, the Halo team used the Unix time representation. Learn about the various approaches to store DateTimes within Cosmos DB, and the associated tradeoffs.

Next steps