Diagrid
Dapr

A Reliable Commerce Cloud at SharperImage.com with Diagrid

SharperImage.com runs 70+ Dapr-enabled microservices on Amazon EKS and processes 80,000+ orders a day at peak, with reliable commerce events built on Dapr pub/sub and the outbox pattern, backed by Diagrid.

At a glance

  • Company: SharperImage.com, US online retailer of home electronics, air purifiers and lifestyle products
  • Platform: Commerce Cloud, a headless ASP.NET Core e-commerce platform on Amazon EKS, plus a few AWS Lambda functions
  • Scale: 70+ microservices, 80,000+ orders per day at peak
  • Dapr APIs: service invocation (gRPC), pub/sub (Kafka), state management (DynamoDB), secrets, resiliency
  • Diagrid: Dapr support, Dapr ops dashboard, 4+ year partnership
  • Cloud resource savings: CPU per service dropped from 3.5 cores to 0.03 cores after moving to Dapr

SharperImage.com runs its Commerce Cloud on more than 70 Dapr-enabled microservices on Amazon EKS and processes over 80,000 orders a day at peaks like Black Friday. Dapr is what keeps the platform resilient. Sidecars decouple services from each other and from infrastructure, Dapr pub/sub delivers every event at least once, and an outbox built on Dapr state management makes sure order events still reach downstream services when a service fails mid-request. The team works with Diagrid for Dapr support and is now piloting Dapr Workflow to replace the outbox.

Diagrid has been SharperImage.com's Dapr partner for over four years. The team has Standard Dapr support from Diagrid and runs the Dapr ops dashboard to check configuration and component health.

The challenge

In January 2022, SharperImage.com's CEO asked the engineering team to retire its in-house microservices framework. The team had spent more than three years moving the platform to ASP.NET Core on that framework, which shipped as a NuGet package inside every service.

The framework had become unreliable, expensive to run and hard to work on:

  • The framework wasn't reliable. When services scaled up, instances lost their registration and stopped processing messages. Events went unprocessed, causing major disruptions at the moments that mattered most, like Black Friday and Cyber Monday.
  • Message processing burned CPU. Each service polled Kafka in infinite loops. To keep up, the team ran five, six, sometimes ten copies of a service.
  • Developers fought the framework. Onboarding took a long time, unit and integration tests were hard to write, and deployments went through a custom CLI with manual steps.

Aaron Olds, software architect at SharperImage.com, set the goal: a reliable platform with less complexity and lower operating cost, so developers could spend their time on customer-facing features. After a hackathon in Portland with Dapr co-creator Yaron Schneider, the team had its first service running on Dapr within minutes and has since moved nearly all of the platform onto Dapr.

Why SharperImage.com works with Diagrid

Moving the services behind every order onto open source Dapr meant SharperImage.com wanted experts it could call on. The team first worked with members of the Diagrid team when they were at Microsoft, and Diagrid has been its Dapr partner for over four years. Under Standard Dapr support, critical issues get a response within four business hours, and Diagrid engineers guide the team through Dapr upgrades, configuration and new features.

Running Dapr in production surfaced a few configuration issues early on, such as component scopes that let Kafka topics reach services that weren't built to handle them. The team now uses the Dapr ops dashboard to validate configuration and check component health, alongside Datadog for application metrics.

“To avoid similar issues in the future, we now rely on Diagrid's [Dapr ops dashboard] to validate our configurations and ensure that everything is set up correctly.”

— Aaron Olds, Software Architect, SharperImage.com

Commerce Cloud architecture

SharperImage.com Commerce Cloud architecture: traffic flows through an AWS Network Load Balancer to an NGINX ingress with a Dapr sidecar, then over mTLS through Dapr service invocation to the internal proxy, order, payment and shipment services, which write to Dapr state stores and a DynamoDB outbox that a Lambda function publishes to Kafka

Customer traffic enters an Amazon EKS cluster through an NGINX ingress that runs with a Dapr sidecar. From there, services call each other through Dapr service invocation, exchange events over Kafka through Dapr pub/sub, and write state through Dapr state management. SQL Server, OpenSearch and DynamoDB store the data, and a few functions run on AWS Lambda.

Resilient events with Dapr and the outbox pattern

Every order on SharperImage.com sets off events that other services depend on. If a service saves its state and then crashes before it publishes the event, the database and the downstream services stop agreeing: the order exists, but nothing else hears about it. The transactional outbox pattern closes that gap by writing the event to an outbox table in the same transaction as the state change, then delivering it from the outbox to the message broker.

Transactional outbox to Lambda: the Dapr-enabled order service writes to AWS DynamoDB, the raw message is delivered to the AWS MSK message broker, and a Lambda function processes it

SharperImage.com built its outbox before Dapr shipped one of its own. Events flow like this:

  1. A service writes the event to an outbox table in DynamoDB through the Dapr state management API.
  2. A trigger on the DynamoDB table invokes an AWS Lambda function for each new entry.
  3. The Lambda function wraps the message in a CloudEvent or in SharperImage.com's internal event envelope and publishes it to Kafka.
  4. Subscribing services consume the event from Kafka through Dapr pub/sub.

Once step 1 succeeds, the event is stored durably. If the service that wrote it fails a moment later, the trigger still fires and the event still reaches Kafka. Dapr pub/sub then delivers it at least once to each subscriber.

“To ensure reliable event messaging we implemented the outbox pattern using Dapr's state management component to DynamoDB. We guarantee that messages were consistently stored and processed even in the case of service failures. This was a significant improvement over our previous approach.”

— Aaron Olds, Software Architect, SharperImage.com

Dapr provides the rest of the platform's resiliency. Each service talks to its Dapr sidecar instead of directly to other services or to Kafka, so one failing service no longer takes others down with it. If a subscriber goes down for a while, its events wait in Kafka and Dapr pub/sub delivers them when it comes back. Dapr's resiliency policies add retries, timeouts and circuit breakers to calls between services without changes to application code.

Together, these let services scale up and down with demand without missing events or losing instance registrations. Those were exactly the failures that made the old framework unreliable during Black Friday and Cyber Monday.

Next: from outbox to Dapr Workflow

SharperImage.com is beginning a pilot of Dapr Workflow to replace its DynamoDB and Lambda outbox, aiming for a simpler and more resilient design. The team had already run proofs of concept with Dapr's built-in outbox, and Workflow goes a step further.

Today a reliable event depends on four pieces: the Dapr state write, the DynamoDB trigger, the Lambda function and its custom envelope, and Kafka. With Dapr Workflow, the multi-step process runs as code inside the cluster, next to a Dapr sidecar. Dapr records the progress of each step, so a workflow that is interrupted by a crash or a redeploy resumes where it stopped instead of starting over. That removes the Lambda hop that runs outside Dapr, and brings Dapr's retries and tracing to the whole flow.

Diagrid is supporting the pilot with guidance and tooling for building and testing workflows.

Results

AreaBefore DaprWith Dapr
CPU per serviceBefore Dapr3.5 coresWith Dapr0.03 cores
Replicas per serviceBefore Dapr5 to 10 to keep up with KafkaWith Dapr2 to 3, kept for resiliency
ScalingBefore DaprLost instance registrations and stalled messagesWith DaprScale up or down without missed events
DeploymentsBefore DaprCustom CLI with manual stepsWith DaprAutomated through Bitbucket Pipelines
SupportBefore DaprFramework maintained in-houseWith DaprStandard Dapr support from Diagrid, a partner for 4+ years

The CPU drop came from moving message handling out of the services' polling loops and into the Dapr sidecar, which pushes each event to an HTTP or gRPC endpoint.

Fewer, lighter replicas let the team run its Kubernetes nodes more efficiently and cut cloud infrastructure costs. Developers no longer edit framework YAML and JSON files to change or scale a service, and spend that time on features for customers.

Additional Resources

Ready to get started?

See how Diagrid can help you run Dapr in production with confidence.

Related Case Studies