A client's e-commerce store with a catalog of 20,000 SKUs lagged on every request. An OpenCart installation on shared hosting with PHP 7.4 delivered a catalog page in 5 seconds — LCP was 8 seconds, half of users left before load. After migrating to PostgreSQL 15 with JSONB attributes and integrating Elasticsearch 8.x, load time dropped to 200 ms, CLS decreased from 0.35 to 0.02. That's how a proper e-commerce store is built — not a template, but an architecture where every detail affects speed and order pipeline.
Development starts not with choosing button colors, but with the business model: inventory management, pricing, logistics, marketing — everything must be aligned before a line of code. Choosing the wrong stack upfront saves time initially but turns into technical debt within a year. We perform a free audit and propose optimal solutions.
Each e-commerce store requires an individual approach: data model, integrations, load. Universal solutions don't exist. Contact us for a consultation on your project — we'll evaluate the architecture and recommend the right stack.
How to Choose a Technology Stack for an E-commerce Store
The stack is determined by three factors: catalog size, integration scenarios, and expected traffic. Typical options:
| Scenario | Stack | Rationale |
|---|---|---|
| Up to 1,000 SKUs, B2C, fast launch | Shopify + custom frontend on Next.js | Shopify handles payments, hosting, PCI DSS. Subscription from $29/month. |
| 1,000–50,000 SKUs, complex filters | Laravel/Django + React/Vue, Elasticsearch | Flexibility in data model, full-text search. Elastic Platinum license ~$2,000/year. |
| High-traffic marketplace | Microservices, Kafka, separate cart/order services | Component-based scaling. |
| B2B with personal accounts and price lists | Custom ERP integration, contract prices | Standard solutions don't cover role logic. |
For most mid-range projects, a monolith with clear module boundaries is optimal — faster to develop, easier to maintain.
Why the Catalog Data Model Is Critical
The catalog data model determines everything else. A common mistake is creating a products table with columns color, size, material directly. This works until the first non-standard product. The correct approach: EAV (Entity-Attribute-Value) or JSONB attributes in PostgreSQL. Example schema:
products (id, sku, slug, base_price, status) product_variants (id, product_id, sku, price_delta, stock) variant_attributes (variant_id, attribute_id, value) attributes (id, name, type, filterable, sortable) For catalogs with heterogeneous products (electronics + clothing + furniture), we use product types — each type defines its own set of attributes. This is how Akeneo PIM works, which we connect for catalogs from 10,000 SKUs.
Search and Filtering
Standard SQL search LIKE '%query%' is unsuitable even for a catalog of 500 items — no relevance, morphology, or synonyms. Options:
- PostgreSQL FTS with
ts_vector— suitable up to ~5,000 products, configure for Russian via ispell or hunspell - Elasticsearch — full-featured: fuzzy search, field boosting, synonyms, percolator for "similar products". According to Elasticsearch Reference, aggregations allow counting documents for each filter value.
- Typesense — simpler to operate, good for small teams
We build filters via Elasticsearch aggregations: users see only those filter values that yield non-zero results. This is faceted search — the ecommerce standard.
How to Implement Faceted Search
- Determine product attributes that will be filters (price, brand, size).
- Create a mapping for the index with correct types (keyword, float).
- Index products with their attributes.
- Run aggregations for each filter in a single query.
- On the frontend, display aggregated values and update results when filters are selected.
Cart and Checkout
The cart is where 60–80% of conversion is lost. Critical decisions:
- Guest cart stored in Redis with TTL of 30 days, merged with server-side on login. Without guest cart, registration becomes a barrier.
- Single-screen checkout statistically outperforms multi-step for B2C. For B2B, the opposite — steps are needed: billing info, delivery address, manager approval.
- Real-time shipping calculation: APIs from CDEK, Boxberry, Nova Poshta, DHL. Rates depend on weight, dimensions, origin point — computed on the fly, not stored in a table.
- Payment gateway: Stripe for international, CloudPayments / YooKassa for Russia/CIS, Fondy / WayForPay for Ukraine. Integration via webhook confirmation; order status changes only after signature verification. Stripe fee: 2.9% + $0.30 per transaction.
Order Management
Order lifecycle is a state machine. States: draft → pending_payment → paid → processing → shipped → delivered → completed. Plus side branches: cancelled, refunded, on_hold. Libraries: winzou/state-machine for Laravel, xstate if part of the logic is on the frontend. Each state transition triggers notifications (email, SMS, push), inventory updates, and logging.
Integrations
Typical set for a full-fledged store:
- 1C / MySklad / Retailio — synchronization of stock and prices via a queue (RabbitMQ/Redis Queue) with a 5–15 minute interval
- CRM (AmoCRM, HubSpot) — automatic transfer of orders and leads
- Email marketing (Klaviyo, Mailchimp, Sendpulse) — trigger sequences: abandoned cart, post-purchase, reactivation
- Analytics: GA4 with Enhanced Ecommerce + server-side GTM for accurate data without ad blockers
Detailed 1C Integration Scheme
For data exchange with 1C, we use CommerceML (cml) — an XML format. A RabbitMQ queue is created where 1C sends changes. A consumer in PHP/Laravel parses the XML and updates the database. Reverse synchronization of orders into 1C — via REST API. All operations are logged for debugging.Performance and SEO
Catalog pages must be cached. Strategy: stale-while-revalidate — serve cache immediately, update in the background. Redis for server-side cache, CDN (Cloudflare) for static assets. Ecommerce-specific SEO:
- Canonical URLs for filter pages — without this, search engines see thousands of duplicates
- hreflang for multilingual stores
- Schema.org markup: Product, Offer, AggregateRating — affects rich snippets
- Pagination via rel="next"/"prev" or infinite scroll with SSR rendering of the first screen
What's Included in Our Work
- Technical specification with functional description and integrations
- Interface prototyping (Figma)
- Backend development: catalog, cart, orders, personal account modules
- Frontend on a modern stack (React/Vue) with responsive design
- Integrations with payment systems, delivery services, warehouse systems
- Testing (unit, integration, load)
- Production deployment and monitoring setup
- Administration documentation
- Post-launch support (one-month warranty for bug fixes)
Timelines and Stages
Typical medium-scale e-commerce store (1,000–10,000 SKUs, standard checkout):
| Stage | Duration |
|---|---|
| Analysis and design | 2–3 weeks |
| Backend: catalog + cart + orders | 4–6 weeks |
| Frontend | 4–6 weeks |
| Integrations (1C, payments, delivery) | 2–4 weeks |
| Testing and launch | 1–2 weeks |
Total: 12–20 weeks for a full project without ready-made templates. Shopify projects with minimal customizations — 4–8 weeks. The key principle: an e-commerce store launches not when everything is ready, but when enough is ready for the first sales. The rest is iterations. Contact us to discuss details.







