Devizur
All insightsE-commerce

Building a Modern E-commerce Platform That Can Scale With Your Business

Scalability across traffic, catalogue complexity, pricing, checkout reliability, integrations and engineering teams—not just request throughput.

Soud Al Raihan16 April 20263 min read
EdgeNext.jsASP.NET CorePostgreSQLRedis

History and context

1990s
Online stores were primarily catalogue + cart + checkout systems.
2000s
Payment gateways, richer CMS platforms and global fulfilment expanded the commerce stack.
2010s
Mobile, omnichannel, APIs and headless commerce separated experience layers from commerce services.
Today
Modern platforms need independent decisions about rendering, business APIs, transactional data, caching, background work and observability.

What actually needs to scale

Traffic is only one dimension. A platform can process high request volume and still fail organisationally if every new promotion or fulfilment rule requires changes across several applications.

Technical scale

Requests, connections, database load, cache pressure, queue throughput.

Business scale

Products, locations, pricing rules, fulfilment types, channels and teams.

Reference architecture

BrowserCDN / EdgeNext.js StorefrontASP.NET Core APIPostgreSQLRedisBackground Jobs
A pragmatic commerce platform separates experience, business logic, durable data and acceleration layers.

Why Next.js at the experience layer

Next.js provides an application framework around React and currently supports both App Router and Pages Router, with App Router being the newer model built around modern React capabilities. For commerce, the architectural benefit is the ability to choose server-rendered and client-interactive boundaries per feature rather than turning the whole storefront into a client-only application.

Next.js / TypeScript
export default async function ProductPage({
  params
}: {
  params: Promise<{ slug: string }>
}) {
  const { slug } = await params;
  const product = await getProduct(slug);

  return (
    <main>
      <ProductSummary product={product} />
      <AddToCart productId={product.id} />
    </main>
  );
}

Why ASP.NET Core owns business rules

The backend should answer business questions rather than merely expose tables.

C#
[HttpPost]
public async Task<ActionResult<CheckoutResult>> Checkout(
    CheckoutRequest request,
    CancellationToken cancellationToken)
{
    var result = await checkoutService.ExecuteAsync(
        request,
        cancellationToken);

    return Ok(result);
}

Transactional modelling with PostgreSQL

Orders should store financial snapshots so later catalogue changes do not rewrite history.

PostgreSQL
CREATE TABLE sales_order (
    order_id BIGSERIAL PRIMARY KEY,
    order_number VARCHAR(40) NOT NULL UNIQUE,
    status VARCHAR(30) NOT NULL,
    subtotal NUMERIC(18,2) NOT NULL,
    discount_amount NUMERIC(18,2) NOT NULL DEFAULT 0,
    tax_amount NUMERIC(18,2) NOT NULL DEFAULT 0,
    total_amount NUMERIC(18,2) NOT NULL,
    created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

Caching where it has a freshness policy

Redis can reduce repeated expensive reads, but every cached object needs an explicit invalidation or expiration policy. ASP.NET Core also provides distributed and hybrid caching abstractions for multi-instance applications.

C#
var product = await hybridCache.GetOrCreateAsync(
    $"product:{productId}",
    async token => await repository.GetAsync(productId, token),
    cancellationToken: cancellationToken);

Keep the checkout critical path short

Place OrderValidate + PriceReserve / OrderPaymentConfirmAsync Integrations
The transaction should finish before non-critical messaging and analytics work.

Idempotency protects money flows

Network timeouts do not prove that a payment failed. Retrying a non-idempotent checkout can create duplicates.

HTTP
POST /api/checkout
Idempotency-Key: 9b86c74d-bd59-4e88-8718-208c6bb90872
Design rule
The server should persist or otherwise reliably recognize the idempotency key for the logical operation and return the existing outcome for safe retries.

Indexes should follow real queries

SQL
SELECT product_id, product_name, fixed_price
FROM product
WHERE shop_id = @shopId
  AND category_id = @categoryId
  AND is_active = TRUE
ORDER BY product_name
LIMIT 24;
SQL
CREATE INDEX ix_product_shop_category_active_name
ON product (shop_id, category_id, product_name)
WHERE is_active = TRUE;

Indexes improve selected read patterns by adding write and storage cost. Performance work should start from measured query plans rather than index count.

Business value and practical considerations

Pros

  • Strong multi-channel foundation
  • Server/client rendering flexibility
  • Relational transaction model
  • Independent cache strategy
  • Clear growth path

Considerations

  • More engineering than hosted commerce
  • Requires DevOps discipline
  • Cache invalidation complexity
  • Cloud and database cost governance
SA
Soud Al RaihanScalable commerce architecture · Devizur

References