All projects
corporate

Taptok — Scaling a Multi-Tenant SaaS to 100K+ Monthly Transactions on AWS

SaaS · Multi-Tenant · AWS · Database Sharding · TDD

Client
Taptok for Business
Industry
SaaS / Digital Business Cards
Location
Gulf Region
Year
2024
Preview the live site

100K+

Monthly transactions handled

on AWS infrastructure

0

Analytical query impact on tx DB

fully decoupled

sub-second

Transactional response time

under any report load

comprehensive

Test coverage (core paths)

TDD enforced

Project brief
Client
Taptok for Business
Industry
SaaS / Digital Business Cards
Location
Gulf Region
Work included
Web Development

Taptok's digital business card platform was approaching the limits of a single-database architecture. Analytical queries were competing with transactional queries, and both were getting slower. We built tenant-based database sharding, decoupled analytics entirely, and maintained TDD throughout — making the rebuilt system safe to keep improving.

01 / Project Overview

The situation

Taptok provides digital business card and contact management infrastructure for Gulf businesses. Each business account is fully isolated \u2014 its own contacts, sharing events, analytics, and profile data. At 100K+ monthly transactions across thousands of tenants, the single-database architecture that worked at launch was becoming the bottleneck. The specific problem was contention between query types. Transactional queries \u2014 creating contact records, logging a card share, updating profile data \u2014 need to be fast and consistent. Analytical queries \u2014 report exports, dashboard aggregates, usage summaries \u2014 are heavy and acceptable to be slightly stale. On a shared database, a long-running analytical query can lock rows or consume I/O that slows down transactional operations for active users. We designed a tenant-based sharding scheme. Tenants are distributed across shards based on a consistent hashing strategy. Application-level routing directs queries to the correct shard transparently \u2014 the application code doesn't know which shard it's talking to. Adding capacity means adding a shard, not vertically scaling a single server. Analytics was completely decoupled. Events flow into Redis, batch jobs aggregate them on a schedule, and results land in a dedicated reporting store that's never on the transactional query path. Active users see sub-second transactional responses regardless of the reporting workload. TDD was enforced throughout the rebuild. Every service class has test coverage before shipping \u2014 the team can change things with confidence.

02 / The Challenge

What had to change

Single-database architecture was approaching capacity. Long analytical queries competed with transactional queries for I/O and locks — active users experienced slowdowns during report generation. Without test coverage, modifying core transaction logic was risky. Scaling vertically was becoming expensive and had a ceiling.

03 / Our Solution

What we changed

Tenant-based sharding with consistent hash routing — horizontally scalable, application-transparent. Analytics decoupled to Redis event pipeline → background aggregation → reporting store. Zero analytical query load on the transactional database. TDD enforced throughout rebuild — comprehensive test coverage on all core transaction paths.

04 / Deliverables & outcomes

What the client gained

  • 01 Horizontal sharding — scale by adding shards not servers
  • 02 Analytics fully off the transactional database
  • 03 AWS (EC2, RDS, Docker) production infrastructure
  • 04 TDD throughout — safe to change, safe to ship
Bring the next constraint

Have a project that needs a clearer way forward?

Discuss the project