CloudQuarks Marketplace
Backend and search performance for a B2B cloud marketplace
- Role
- Backend Engineer (at Hexalytics)
- Client
- Redington Group · Hexalytics
- Timeline
- Sept 2025 - Mar 2026

Backend services for an enterprise B2B and B2C cloud marketplace on Medusa.js: vendor onboarding, catalog management, subscription pricing and order workflows across 200,000+ store-specific SKUs. Advanced search with several filters went from about 40 seconds to under 6 seconds.
- Rewrote the slow catalog queries to remove redundant joins and full table scans on high-cardinality tables.
- Added Redis caching on AWS ElastiCache with tag-based invalidation, so a catalog or pricing change clears only the results it affects.
- Moved pagination from OFFSET/LIMIT to keyset (cursor-based) pagination on indexed sort keys, so deep catalog pages stay fast even at 200,000+ SKUs.
- Built Medusa.js modules and REST APIs for subscriptions, vendor onboarding and order fulfilment.
- Worked directly with client stakeholders through architecture discussions, production deployments and debugging.
- Node.js
- Medusa.js
- PostgreSQL
- Redis
- Docker
- AWS
Search latency: before and after
- Advanced search with 3+ filters. Before: ~40s. After: under 6s.
- Caching. Before: no cache existed. After: repeat searches are served from Redis, with tag-based invalidation.
- Catalog size during the work: 200,000+ store-specific SKUs.
Measured with EXPLAIN (ANALYZE, BUFFERS) on production-scale data.
Environment: Medusa.js services on AWS, with PostgreSQL and Redis.
Problem and objectives
Catalog search with several active filters was taking up to 40 seconds, and sometimes timing out. Each request combined price ranges, vendor availability and custom attributes across 200,000+ store-specific product variants, and the query plan fell back to scanning most of the catalog.
Architecture

Diagram: the CloudQuarks search request path.
I started with EXPLAIN (ANALYZE, BUFFERS) on the slow queries, which showed sequential scans and expensive joins against unindexed JSONB attributes. Composite B-Tree indexes for the common filter combinations and GIN indexes on the JSONB metadata, together with keyset pagination, removed the full scans.
A Redis layer sits on top of that. Cache keys are a deterministic hash of the normalised filter set, and catalog or pricing updates invalidate entries by tag, so a price change clears only the results it affects. With all of it in place, advanced search responds in under 6 seconds, down from about 40. The services are modular Medusa.js modules deployed on AWS.
Tradeoffs
The composite and GIN indexes make reads faster and every catalog write a little slower, and they take space, so I indexed the filter combinations people actually use instead of every attribute.
Caching trades freshness for speed. Tag-based invalidation clears affected results when a price or product changes, and a short TTL is the backstop if an invalidation is missed. A cache miss still pays the full query cost, which is why the query was fixed before the cache was added.
Keyset pagination keeps deep pages cheap on indexed sort keys, but it cannot jump to an arbitrary page number.