← Back to Blog

Scale Fast and Easy with the Projector Pattern

Architecture Microservices Patterns

The Microservices Dilemma

Microservices and Domain Driven Design are powerful tools we can use to break up monoliths and design new systems. What we don’t always talk about is the extra complexity this can bring to our systems. As a system grows scaling can become an issue as well. Other teams just want to display the product details, but they have to orchestrate several API calls. Traffic is climbing and spikes can interrupt your product services. What can you do to deal with these new problems?

Domain based Microservices

Microservices are a great way to partition a system along domains. For example, imagine you are a used board game company. You have 3 microservices based around your domains:

  • A product service that has a standard set of details like name and description
  • A condition service that represents anything unique about this game like missing pieces or damage
  • An Item service that tracks each individual game in inventory

Domain Services

This works great for your business to independently scale and develop features in these domains. As the site is building traffic this is causing a couple of problems:

  • Complexity: putting together the details of an item requires calling all of the services
  • Performance: calling multiple services adds latency
  • Scale: the services need to scale together as site traffic grows and to handle domain-specific scale requirements

A Solution: The Projector Pattern

The projector pattern allows the current state of a system to be captured in a projection based on the sources of truth. To take advantage of it we need to identify a triggering event to build a projection, a desired data model for the projection, and where to gather that data (the sources of truth).

Projector

Understand your customer

To make this useful you want to identify and understand the use cases for reading data. This customer (or customers) of your services is your audience that you will base the projection data model on. The customer of your services is probably an experience like a website or an app, but it might also be internal teams. Use your projection to build the data model they need for them.

Optimized Reads

Users or clients of the system now have a simple way to get the details they need quickly. They only need to call the projection service to get the data rather than calling the individual services.

Users Get Projections

Benefits

Scaling and Performance

How does this benefit our overall system performance? Our Projection service typically gets about 10X more reads than writes in our production system. Despite the much higher read traffic about 80% of our database’s RUs are consumed by writes. Since only a fraction of our RU usage is consumed by reads this makes it easy to continue adding more clients without worrying about the need to scale up our databases.

Traffic Spikes

Any traffic spikes from clients will hit our Projection service instead of our operational services. This keeps our system isolated from external spikes so we can continue processing transactions internally with no impact from traffic spikes.

Things to watch out for

This is not a caching system and shouldn’t be confused with a cache. Caching is typically done by adding an item the first time it is requested and then using a purging scheme such as least recently used. The projection is useful when any item is about equally likely to be accessed and each item is not accessed frequently. The projector design is also durable so you don’t have to worry about rebuilding it like a cache. Caching will use less memory when there are “hot” items that get accessed frequently, but many others that are rarely or never used.