Armakuni Contact us
← All case studies

A paid email app was competing with free ones.
It needed reasons to stay, and a cheaper engine to run.

A cross-platform consumer email service, syncing more than 13 million messages a day across macOS, Windows, iOS and Android, was close to being shut down: engagement had stalled and its bare-metal infrastructure was expensive and fragile. We built the features that gave subscribers reasons to stay, rebuilt the background processing on Amazon EKS with workers for each kind of job, and put routine recovery on automation.

Before

Free alternatives made it hard to justify paying for email.

An engineer had to stay awake to answer every incident.

After
~25%lower operating cost
~2×faster incident response
  • Read receipts, templates, link sharing and adaptive dark mode turned retention around.

As the company reported.

Free alternatives made it hard to justify paying for email

The subscription service had to earn its place beside the free clients already installed on every device. It offered much the same mailbox, so churn was outpacing new subscribers, and the team was preparing to close it.

Meanwhile engineering time went into bare-metal hosts and hand-managed configurations. Fragile dependencies across four operating systems broke production without warning, because there was no shared codebase. Capacity was sized for peak and paid for at peak all day.

An engineer had to stay awake to answer every incident

Recovery depended on an engineer being on call, even for incidents with a known fix, so time to recovery was set by how fast a person could get to a keyboard. One failure domain meant any problem could spread across the service.

The plan aimed to keep subscribers around while giving the platform room to cost less

The product needed features worth paying for, built once and shared across all four platforms, and at the same time the platform needed to cost less to run and recover from failures on its own, because the business could only keep building if both held true.

How we built it

4 decisions, in the order we made them. Each one says what we did and why, with what it did drawn beside it.

  1. Features worth paying for, built once
  2. Each kind of job gets its own worker
  3. Capacity that follows the demand, at committed prices
  4. Each unit runs on its own, and its runbooks recover it from failures without anyone being paged

Features worth paying for, built once

Built withS3RDS
Built once Read receiptsTemplatesExpiring linksAdaptive dark mode in every app
The engineering

A single codebase now runs on macOS, Windows, iOS and Android. A feature is built once rather than four times, and a dependency change can only break in one place. On that base, the product work added:

  • Read receipts let a sender know when an email has been opened.
  • Reusable templates and snippets cut repeated emails down to one click.
  • Expiring links let someone share an email, backed by S3 and RDS with a 30-day default expiry, so the recipient sees it with its formatting and attachments, without needing an account.
  • Dark mode adapted on its own, following the time of day.

Each kind of job gets its own worker

Built withEKSSQSDynamoDBS3RDSEC2
One pool for every job Crawling Actions Notifications
The engineering

All workloads once sat on the same undifferentiated servers, so a sync storm could starve push notifications. Now:

  • Containerized workloads run on EKS, with worker groups specialized for crawling, actions, notifications and API traffic.
  • SQS and Gearman distribute asynchronous jobs, so background processing scales separately from interactive requests.
  • DynamoDB holds message metadata and tracking state, S3 stores attachments and shared assets, and account and sharing data, which needs relational structure, sits in RDS, each store chosen for how its data gets used.
  • Public load balancers front the API tier and internal ones spread work across the EC2 worker pool, so each layer scales on its own.

The team also put a SQLite-and-Thrift metadata cache on the device, SQLite behind a Thrift interface, holding 60 days of email metadata, or 15 during a trial, so the message list renders almost at once and the back end is shielded from the read fan-out an email client generates.

Crawling, notifications and the API each run on their own workers, so a busy job in one can't slow the others.

Capacity that follows the demand, at committed prices

Work arrivingCompute
The engineering

Autoscaling adjusts capacity across every tier, and commitment-based pricing (reserved instances and savings plans) covers the steady part of the demand, which a consumer email service has every hour of every day. Serverless logic takes on work that doesn't need always-on servers.

Each unit runs on its own, and its runbooks recover it from failures without anyone being paged

Built withCloudWatch
A unit failsIts runbook recovers itOn call only for judgment
The engineering

Workloads are spread across independent, federated units that each handle their own crawling, actions and notifications, which keeps a failure inside its own unit. CloudWatch alerting is scoped the same way, unit by unit, and that keeps a real signal from getting buried. AWS Systems Manager runbooks detect, contain and fix routine failures on their own. The on-call engineer is paged only for incidents that need judgment, and the separate worker groups tell them exactly where to start looking.

What we'd tell another CTO

1The product features justified the platform work, because they gave the business a reason to keep investing in the engine underneath.
2Workers are specialized by job, so a storm in one workload can't starve another, and each store matches its data because metadata, attachments and accounts need different things. The team commits on the baseline and scales on the peaks, which is where most of the 25% saving came from, and automates the known fixes so people are kept for the incidents that actually need them.

What else changed

As the company reported.

  • Read receipts, templates, link sharing and adaptive dark mode turned retention around for a product that had been heading toward closure.
  • One codebase runs across all four platforms, with separate workers handling crawling, actions, notifications and the API, syncing more than 13 million messages a day.

What comes next

More features on the shared codebase, and the same runbook approach extended to more failure types.

How we'd do it today

This project came before our current offers. Here's how we'd approach the same work now.

AK Run, our AI-native managed service, would take on the whole service as one team, day and night, so the company wouldn't need a night shift of its own. That covers production, including the EKS worker groups, the federated units and the bill, with the known-fix runbooks already in place. A bug in the sync or notification code gets fixed in the code, tested and shipped through the company's own pipeline, and patches, upgrades and certificates are dealt with before they turn urgent. Its AI agents take the first look at every alert and draft the fix, and a named engineer confirms the cause. For the companies we run, the median AWS bill falls 40% in the first quarter.

For the next features, the company's engineers would lead small crews of AI agents on AK AI Factory, with linters and tests enforcing the architecture on every change, so the unified codebase stays unified whoever wrote the code, and a person reviewing and merging every change.

Have a problem like this one?

A free workshop: a few hours with the architects who'd do the work, on your own systems. No cost.

Book a free workshop