Polar Has a Free API: Add Subscriptions and Donations to Your Open-Source Project in 10 Minutes

You built an open-source tool that thousands of developers use. Your GitHub repo has 2,000 stars. But your “Buy Me a Coffee” button generated $12 last year. The problem isn’t that people don’t want to support you — it’s that existing monetization tools weren’t built for developers. Polar was.

What Polar Actually Does

Polar is an open-source billing and monetization platform built specifically for developers and open-source maintainers. Think Stripe plus GitHub Sponsors, but with a developer-first API and features designed around how OSS projects actually work: issue funding, subscriptions, one-time donations, and digital product sales.

Polar is fully open-source (Apache 2.0) and can be self-hosted. Their hosted platform at polar.sh has no monthly fee — they take a small percentage of transactions only when you earn. The REST API is clean, well-documented, and secured with OAuth2 or API keys.

The critical difference from Patreon or Buy Me a Coffee: Polar integrates deeply with GitHub. You can fund specific issues, reward contributors automatically, and tie paid benefits to GitHub actions — like giving subscribers access to a private repo or Discord role.

Quick Start: Polar API

Get your API token from polar.sh → Settings → Developers → New Token.

export POLAR_TOKEN="your_token_here"

# List your products/subscription tiers
curl -s https://api.polar.sh/v1/products 
  -H "Authorization: Bearer $POLAR_TOKEN" | jq '.items[] | {id, name, price_amount}'

Create a subscription tier:

curl -X POST https://api.polar.sh/v1/products 
  -H "Authorization: Bearer $POLAR_TOKEN" 
  -H "Content-Type: application/json" 
  -d '{
    "name": "Pro Supporter",
    "description": "Support development + priority issue responses + private Discord access",
    "prices": [{
      "type": "recurring",
      "amount_type": "fixed",
      "price_amount": 900,
      "price_currency": "usd",
      "recurring_interval": "month"
    }]
  }'

Check active subscribers:

curl -s "https://api.polar.sh/v1/subscriptions?active=true" 
  -H "Authorization: Bearer $POLAR_TOKEN" | jq '{
    total: .pagination.total_count,
    subscribers: [.items[] | {email: .customer.email, tier: .product.name}]
  }'

3 Practical Use Cases

1. GitHub Issue Funding

Polar’s flagship feature: let users pledge money to get specific bugs fixed. When you close a funded issue, contributors get paid automatically.

curl -s "https://api.polar.sh/v1/issues?organization=YOUR_ORG&repository=YOUR_REPO&is_badged=true" 
  -H "Authorization: Bearer $POLAR_TOKEN" | jq '.items[] | {
    title: .title,
    funding_goal: .funding.funding_goal.amount,
    pledged: .funding.pledges_sum.amount
  }'

Add a funding badge to your README:

[![Fund with Polar](https://polar.sh/embed/fund-label.svg?org=your-org)](https://polar.sh/your-org)

When you merge a PR that closes a funded issue, Polar handles reward distribution automatically.

2. Automate Subscriber Benefits with Webhooks

Polar fires webhooks on subscription events. Grant GitHub repo access automatically on new subscription:

const express = require('express');
const app = express();

app.post('/polar/webhook', express.raw({type: 'application/json'}), async (req, res) => {
  const event = JSON.parse(req.body);

  if (event.type === 'subscription.created') {
    const githubUsername = event.data.customer.metadata?.github_username;
    if (githubUsername) {
      await fetch(`https://api.github.com/repos/YOUR_ORG/premium-content/collaborators/${githubUsername}`, {
        method: 'PUT',
        headers: { 'Authorization': `token ${process.env.GITHUB_TOKEN}` },
        body: JSON.stringify({ permission: 'pull' })
      });
    }
  }

  if (event.type === 'subscription.revoked') {
    const github = event.data.customer.metadata?.github_username;
    await fetch(`https://api.github.com/repos/YOUR_ORG/premium-content/collaborators/${github}`, {
      method: 'DELETE',
      headers: { 'Authorization': `token ${process.env.GITHUB_TOKEN}` }
    });
  }

  res.sendStatus(200);
});

Automatic access management — no manual work, no forgotten cancellations.

3. Checkout Links for Digital Products

Sell docs, templates, or premium extensions with one-click checkout:

curl -X POST https://api.polar.sh/v1/checkouts/custom 
  -H "Authorization: Bearer $POLAR_TOKEN" 
  -H "Content-Type: application/json" 
  -d '{
    "product_id": "YOUR_PRODUCT_ID",
    "success_url": "https://yoursite.com/thank-you?checkout_id={CHECKOUT_ID}",
    "customer_email": "[email protected]",
    "metadata": { "source": "readme_cta" }
  }' | jq '{ checkout_url: .url, expires_at: .expires_at }'

Drop the URL in your README, docs, or email. Each click goes to a frictionless checkout.

Why This Matters

Open-source sustainability is broken. Polar is the first platform that truly understands the developer workflow: GitHub-centric, API-first, developer-controlled. The issue funding model changes the entire dynamic — instead of hoping people donate, you give them a direct line to influence your roadmap.

For SaaS developers, Polar also competes with Stripe Billing for simple subscription needs — with zero monthly platform fee and developer experience that feels designed by engineers, not product managers. If you maintain any open-source project with real users, set up Polar before you burn out.

Need custom data extraction or web scraping solutions? I build production-grade scrapers and data pipelines. Check out my Apify actors or email me at [email protected] for custom projects.

Follow me for more free API discoveries every week!

Event Sourcing From Scratch: Why Your Database Has Been Lying to You

Traditional databases lie by omission. They show you the current state of your data — but not how it got there. You see that a user’s balance is $500. You don’t see that they deposited $1,000, bought a $400 item, got a $200 refund, then paid a $300 subscription. The history is gone, overwritten, reduced to a single number.

Event sourcing fixes this by storing every state change as an immutable event. It’s the difference between a bank balance and a bank ledger. I’ve worked with event-sourced systems in production, and they solve problems that traditional CRUD architectures literally cannot — but they also introduce complexity you need to be honest about.

The Bank Ledger Analogy

Banks figured this out centuries ago. They don’t store your balance by overwriting a number. They store every transaction as a separate line item:

+$1,000 (deposit)
-$400   (purchase)
+$200   (refund)
-$300   (subscription)
= $500  (derived balance)

Your balance is derived from replaying the history. That’s event sourcing. Every state change becomes an immutable fact. The current state is just a projection — a materialized view built by replaying events.

Who Actually Uses This?

Event sourcing isn’t theoretical. Major production systems run on it:

  • Financial systems — every transaction is an event, audit trails are built-in
  • E-commerce platforms — order lifecycle from placement through fulfillment
  • Event ticketing (Ticketmaster, Eventbrite) — seat holds, releases, purchases
  • Version control (Git) — every commit is an event, the working directory is a projection
  • Kafka-based architectures — Kafka’s append-only log is fundamentally an event store

LinkedIn processes over 7 trillion messages per day through Kafka. That’s event sourcing at planet scale.

The Core Architecture

An event-sourced system has a few key components:

The Event Store — an append-only log where events are written. You never update or delete events. Each event has a type, timestamp, aggregate ID, and payload. EventStoreDB, Apache Kafka, and even PostgreSQL with an append-only table can serve as event stores.

Events — immutable facts about what happened. Not “set balance to 500” but “deposited 1000,” “purchased item for 400,” etc. Events are past tense because they’ve already happened. You can’t argue with facts.

Aggregates — domain objects that process commands and emit events. An Order aggregate might accept a “PlaceOrder” command and emit an “OrderPlaced” event.

Projections — read models built by replaying events. You might project the same events into a “current balances” table, a “transaction history” view, and a “monthly spending report.” Different shapes from the same data.

CQRS: The Natural Companion

Event sourcing naturally separates writes (appending events) from reads (querying projections). This is Command Query Responsibility Segregation — CQRS. Your write model is the event store. Your read models are projections optimized for specific queries.

This separation means you can scale reads and writes independently. Your event store handles high write throughput. Your projections can be denormalized, cached, and replicated for fast reads. Different projections can use different databases — one in PostgreSQL for relational queries, another in Elasticsearch for full-text search.

Snapshots: The Performance Escape Hatch

Replaying 10 million events to rebuild state is slow. Snapshots solve this: periodically save the current state, then only replay events after the snapshot. An aggregate with a snapshot at event 9,990,000 only needs to replay the last 10,000 events instead of all 10 million.

When You Should Use Event Sourcing

It’s a good fit when:

  • Audit trails matter — finance, healthcare, compliance
  • You need temporal queries — “what was the state at 3pm Tuesday?”
  • Multiple read models from the same data
  • Event-driven architecture is already your pattern
  • Debugging production — you can replay exactly what happened

When You Shouldn’t

Be honest with yourself about the downsides:

  • Complexity is real. CRUD is simpler. If your domain is straightforward, event sourcing is over-engineering.
  • Eventual consistency. Projections lag behind events. If your users need instant read-after-write consistency, you need careful design.
  • Schema evolution is painful. Events are immutable, but your event schema will change. Upcasting old events to new formats is tedious work.
  • Storage grows forever. You’re keeping every event. Compaction and archival strategies become necessary.
  • Tooling is less mature. Fewer ORMs, fewer tutorials, smaller community than traditional CRUD.

My honest take: most applications don’t need event sourcing. But for the ones that do — complex domains with audit requirements, temporal queries, or multiple downstream consumers — nothing else comes close.

Your JavaScript Array is a Hash Map in Disguise

TL;DR: JavaScript arrays are fundamentally objects where integer keys are treated as strings. To save performance, engines like V8 attempt to optimize these into contiguous memory blocks (Elements Kinds). However, mixing types or creating sparse “holes” triggers a de-optimization to Dictionary Mode, moving data from the 1ns CPU cache to 100ns RAM lookups.

If you have ever wondered why typeof [] returns "object", the answer isn’t just “JavaScript is weird.” It is an architectural warning. In the underlying C++ of the V8 engine, arrays are not fixed-size contiguous memory buffers by default. They are hash maps—specifically, exotic objects that map integer keys to values. While this makes JS incredibly flexible, it creates a massive performance hurdle that the engine has to work overtime to solve.

Why does typeof return “object” for a JavaScript array?

JavaScript arrays are keyed collections that inherit from the Object prototype, meaning they are essentially specialized objects where the keys are property names. Even though we access elements using arr[0], the engine internally treats that index as a string key "0" to maintain compliance with the language specification.

Under the hood, this means a standard array doesn’t have a guaranteed memory layout. In a language like C, an array of four integers is a single 16-byte block of memory. In JavaScript, a naive array is a collection of pointers scattered across the heap. To find an element, the engine has to perform a hash lookup, which is computationally expensive compared to a simple memory offset. This architectural choice is why V8 spends so much effort trying to “guess” when it can treat your array like a real, contiguous block of memory.

How does V8 use “Elements Kinds” to optimize performance?

V8 uses a system called Elements Kinds to track the internal structure of an array, attempting to store data in the most efficient C++ representation possible. If you create an array of small integers, V8 labels it PACKED_SMI_ELEMENTS and stores it as a contiguous block of memory, allowing the CPU to access it with near-zero overhead.

This optimization is all about hardware efficiency. When data is contiguous, it lives in the CPU’s L1 or L2 cache. The CPU can use “prefetching” to load the next few elements into the cache before your code even asks for them. Retrieval from the cache takes about 1 nanosecond. However, if the array becomes a hash map (Dictionary Mode), the CPU has to engage in “pointer chasing.” It must go all the way to the system RAM—which can take 100 nanoseconds or more—to find the memory address of the next bucket in the hash map. That 100x latency jump is the hidden tax of unoptimized JavaScript.

What triggers the transition to Dictionary Mode?

The transition from a fast, packed array to a slow hash map is often a one-way street. V8 starts with the most optimized state and “downgrades” the array as you introduce complexity, such as mixing data types or creating large gaps between indices.

If you have a PACKED_SMI_ELEMENTS array and you push a floating-point number into it, the engine transitions it to PACKED_DOUBLE_ELEMENTS. If you then push a string, it becomes PACKED_ELEMENTS (a generic array of pointers). The most destructive action, however, is creating a “holey” array. If you define let a = [1, 2, 3] and then suddenly set a[1000] = 4, V8 refuses to allocate 997 empty memory slots. Instead, it panics and converts the entire structure into DICTIONARY_ELEMENTS. Once an array is downgraded to a dictionary, it rarely—if ever—gets promoted back to a packed state.

// Starts as PACKED_SMI_ELEMENTS (Fastest)
const arr = [1, 2, 3]; 

// Transitions to PACKED_DOUBLE_ELEMENTS
arr.push(1.5); 

// Transitions to DICTIONARY_ELEMENTS (Hash Map)
// This creates a 'hole', triggering a full de-optimization
arr[1000] = 42; 

Why do these 100ns delays matter in intensive tasks?

In standard UI development, a 100ns delay is invisible. However, in high-throughput backend processing or 60fps graphical programming, these delays are catastrophic. In a requestAnimationFrame loop, you have a hard limit of 16.6ms to finish all calculations. If you are iterating over thousands of “arrays” that are actually hash maps, the constant round-trips to RAM will eat your frame budget and cause visible stuttering.

Similarly, if you are building a data-intensive microservice that processes millions of JSON objects, the cumulative cost of hash map lookups instead of direct memory access can result in a 10x or 100x decrease in total throughput. This is why tools like TensorFlow.js or high-performance game engines use TypedArrays (like Int32Array), which bypass this “Elements Kind” guessing game entirely and force the engine to use contiguous memory.

V8 Array State Transitions

State Description Latency
PACKED_SMI Contiguous small integers ~1ns (Cache)
PACKED_DOUBLE Contiguous floats ~1ns (Cache)
HOLEY_ELEMENTS Array with missing indices Variable (Slower)
DICTIONARY_ELEMENTS Pure Hash Map (De-optimized) ~100ns (RAM)

FAQ

How can I prevent my arrays from becoming hash maps?
Initialize your arrays with their final size if possible and avoid “holey” assignments. Most importantly, keep your arrays monomorphic—meaning, don’t mix integers, strings, and objects in the same collection.

Are TypedArrays immune to this de-optimization?
Yes. Int32Array, Float64Array, and others are backed by an ArrayBuffer. They have a fixed length and a fixed type, which guarantees they stay as contiguous blocks of memory regardless of what you do with the data.

Does deleting an element make an array a hash map?
Using the delete keyword on an array index (e.g., delete arr[2]) creates a hole, which transitions the array to a HOLEY state. While it might not immediately hit Dictionary Mode, it significantly slows down access because the engine must now check the prototype chain for that missing index.

The Identity Trap That Keeps Senior Devs From Reaching Staff

I spent years trying to become the best coder on my team. And it worked — right up until it became the thing holding me back.

Here’s what nobody tells you about the Senior-to-Staff jump: it’s not a skills upgrade. It’s an identity crisis.

The Ceiling Nobody Warns You About

After 5-8 years of grinding, most developers reach Senior and feel like they’ve made it. You’re fast, you’re reliable, you solve hard problems. Your PRs are clean. You’re the person people come to when something’s broken.

Then you stay there. For years.

According to levels.fyi data, the median time at Senior before reaching Staff is 4-6 years — but many engineers never make the jump at all. The drop-off is steep: most companies have 3-5x more Seniors than Staff engineers.

The common assumption is that you need to be even better at coding. Write even more elegant solutions. Ship even faster. But that’s exactly the trap.

The Identity Problem

When “I’m the best coder in the room” is your identity, you optimize for the wrong things. You take on the hardest implementation work yourself instead of delegating it. You solve problems at the code level when the real issue is architectural. You measure your value by your personal output.

Staff engineers get promoted for a fundamentally different skill: making everyone else more productive.

That means writing the document that prevents three teams from building the same thing. Running the design review that catches a scaling problem before it ships. Saying “we shouldn’t build this at all” when everyone’s excited about a feature.

What Actually Changes

The shift looks something like this:

Senior mindset: “I’ll implement this complex feature myself because I can do it fastest.”

Staff mindset: “I’ll design the system so a mid-level engineer can implement it safely, and I’ll focus on the parts that affect three other teams.”

Will Larson’s Staff Engineer book surveyed hundreds of Staff+ engineers. The consistent pattern: they stopped being the person who writes the most code and became the person who ensures the right code gets written.

This isn’t about writing less code. Plenty of Staff engineers still code daily. It’s about choosing where your code has the highest leverage. A week spent on a shared library that eliminates duplicated work across five teams is worth more than a month of heads-down feature work.

The Uncomfortable Part

Letting go of your identity as “the best coder” feels like losing something. You spent years building that reputation. Your confidence is rooted in technical skill. Walking into a room and not being the person with the cleverest solution feels… wrong.

But the engineers who plateau at Senior are almost always the ones still measuring value by personal output. I’ve seen it play out dozens of times. Brilliant engineers, stuck for years, because they kept doing the thing that got them promoted last time.

How to Actually Make the Shift

Three things that work:

1. Track your multiplier effect. Instead of “I shipped feature X,” start thinking “I unblocked 4 engineers this week” or “my RFC prevented a 3-month rewrite.” If your impact disappears when you take a vacation, you’re not operating at Staff level.

2. Volunteer for the unglamorous work. Design documents. Oncall improvements. Cross-team coordination. Migration plans. This work is invisible and boring and it’s exactly what differentiates Staff engineers.

3. Develop opinions about systems, not just code. Staff engineers have strong, well-reasoned views about architecture, team structure, and technical direction. Not “this function should use a map instead of a loop” but “this service boundary is wrong and here’s why it’ll cause problems in 6 months.”

The hardest part isn’t learning new skills. It’s letting go of the identity that got you here. But on the other side of that discomfort is a career that scales — one where your impact isn’t limited by how many hours you can personally code.

Scalable Proximity Search: Why Geohashing Beats Radius Queries

TL;DR: Geohashing maps 2D coordinates to a 1D string using recursive binary partitioning and bit interleaving. By encoding these bits into a Base-32 string, we leverage B-Tree prefix matching for efficient spatial lookups, bypassing the high CPU costs of Haversine distance calculations at scale.

Calculating Haversine distances for 10,000 moving objects per tick is a disaster for database performance. Standard SQL radius queries aren’t built for high-concurrency spatial updates; they are computationally heavy and fail to scale because they require calculating the distance between the query point and every potential candidate in the dataset. To keep latency low, you need to stop thinking in floating-point coordinates and start thinking in B-Tree friendly strings. This is where geohashing comes in, moving the heavy lifting from the CPU to the database index.

How does binary partitioning resolve geographic coordinates?

Binary partitioning recursively divides the map into smaller quadrants, assigning a 0 or 1 based on whether a point falls in the lower/left or upper/right half of the current bounding box. This creates a deterministic bitstream representing a specific geographic area rather than a precise point.

I recently posted a video about geohashing because it is the most efficient way to handle real-time location data. We start by looking at the globe vertically. If a coordinate is in the Northern hemisphere, we assign a 1; if it is in the Southern hemisphere, a 0. We then take that specific hemisphere and split it again. Is the point in the upper or lower half of that new section? This recursive halving continues until we reach the desired resolution. We perform the exact same operation horizontally for longitude (Left/Right splits), resulting in two separate binary streams that describe the point’s location with increasing precision.

Why do we interleave bitstreams for 1D spatial indexing?

Interleaving, also known as bit-zipping, alternates bits from the latitude and longitude streams to create a single sequence that preserves 2D proximity within a 1D format. This process follows a Morton order curve (or Z-order curve), which maps multi-dimensional data to one dimension while maintaining the locality of the data points.

In a standard implementation, the first bit of the latitude stream is followed by the first bit of the longitude stream, then the second bit of each, and so on. This ensures that the resulting combined bitstream—and the subsequent geohash string—represents a specific “tile” on the map. Because the bits are interleaved, points that are close together in a 2D space are highly likely to share the same prefix in their 1D bitstream.

Bit Index (i) Latitude Bit (V_i) Longitude Bit (H_i) Interleaved Result (V_0 H_0 … V_i H_i)
0 1 0 10
1 0 1 1001
2 1 1 100111
3 0 0 10011100
4 1 1 1001110011

How does Base-32 encoding optimize database lookups?

Base-32 encoding converts the final interleaved bitstream into a compact, human-readable string using a specific 32-character alphabet (0-9, b-z) that deliberately excludes ambiguous characters like a, i, l, and o. This representation is highly efficient for database indexing because strings are stored lexicographically in B-Trees, allowing for lightning-fast range scans.

When a taxi app needs to find drivers near you, it does not calculate the distance to every driver in the city. It identifies your geohash—for example, gcpvj0—and queries the database for any driver whose geohash starts with the same prefix. This turns a complex spatial intersection into a simple string comparison. Since the database index is sorted, the system can find all records within the same geographic tile by performing a single index seek followed by a range scan, which is significantly faster than any geometric calculation.

FAQ

What is a Z-order curve and how does it relate to geohashing?
A Z-order curve is a space-filling curve that visits every point in a multi-dimensional grid while preserving the locality of points. Geohashing uses this curve by interleaving bits; the path the bits follow as you increase precision looks like a repeating ‘Z’ shape. This is what allows us to represent 2D data in a 1D string index without losing spatial context.

Why does the geohash alphabet exclude certain letters?
The standard geohash alphabet (the Crockford-inspired Base-32) excludes the letters ‘a’, ‘i’, ‘l’, and ‘o’ to prevent human transcription errors and character confusion. This makes the hashes more robust when being passed through URLs, logged in debugging consoles, or manually entered by engineers.

How do you handle the ‘boundary problem’ where nearby points have different hashes?
Because the Z-order curve occasionally ‘jumps’ (for example, at the equator or the prime meridian), two points can be centimeters apart but have entirely different geohash prefixes. To mitigate this, production proximity services do not just search the user’s current geohash tile; they calculate and query the eight immediate neighboring tiles as well.

Cheers.

The Context Crisis: Why Giving AI More Context Is Becoming the Hardest Problem in Development in 2026

n 2026, developers have access to powerful AI coding models with massive context windows — some reaching 1 million tokens. Yet many teams are discovering that more context doesn’t automatically mean better results. Instead, it has created a new bottleneck: the Context Crisis.
AI tools often generate plausible but incorrect code when they lack deep, accurate understanding of the specific codebase, architecture, standards, and business rules. The result? Developers spend significant time cleaning up, refactoring, and fixing AI output that doesn’t align with their environment.
What the Data Shows
Recent reports highlight this growing challenge:

Stack Overflow’s coverage of DeveloperWeek 2026 notes that AI coding tools without proper company context force developers into “janitorial work” — reorganizing and fixing code that ignores internal standards and architecture.
Multiple 2026 analyses point to the productivity paradox: while 84% of developers use AI tools, trust remains low (around 29–33%), and much of the promised time savings is lost to reworking “almost right” outputs.
Context has emerged as the real limiter of AI’s potential. Without rich, relevant context, even the best models (like Claude 4.6 Opus or GPT-5.2) produce code that looks good but fails in real-world integration, security, or scalability.

The core issue is that Large Language Models treat all input as equal. They struggle to prioritize what matters most in a complex enterprise codebase — custom patterns, deprecated internal libraries, compliance requirements, or team-specific conventions.
Why Context Is So Difficult in 2026

Scale and Fragmentation — Modern codebases span multiple repositories, services, and documentation sources. Feeding everything into an AI quickly hits practical limits or introduces noise.
Dynamic Nature — Codebases evolve rapidly. Static context quickly becomes outdated, leading to hallucinations or suggestions based on old patterns.
Human Judgment Gap — Deciding what context to provide (and how to structure it) requires deep systems knowledge — the very skill AI is supposed to augment.
Agentic Complexity — With the rise of multi-agent systems and autonomous workflows, context must now flow correctly between agents, tools, and human oversight.

This creates a hidden tax: developers toggle between prompting, verifying, and manually injecting missing context, increasing cognitive load and context switching.
Practical Approaches to Tackle the Context Crisis
Teams that are succeeding in 2026 are treating context engineering as a first-class discipline:

Context Layering — Build structured context providers: codebase indexes, architecture decision records (ADRs), API specs, and golden-path templates that AI can reliably access.
RAG + Retrieval Systems — Use advanced Retrieval-Augmented Generation tuned specifically for internal code and documentation, with relevance ranking and freshness checks.
Agent Memory Management — Implement persistent, scoped memory for agents instead of dumping everything into one prompt.
Human-in-the-Loop Context Curation — Create lightweight processes where seniors or platform teams curate and maintain high-quality context packs for common tasks.
Tooling for Context Awareness — Adopt or build tools that automatically surface relevant files, recent changes, and team standards during AI interactions.

The Bigger Picture for Developers
The Context Crisis reveals that AI success in 2026 depends less on raw model intelligence and more on how effectively we bridge the gap between generic training data and our specific engineering reality.
The most valuable skill shifting from pure coding to context orchestration — knowing what the AI needs to know, how to deliver it cleanly, and how to verify the outcome.
Teams that invest in strong context systems will capture the real productivity gains from AI. Those that don’t will continue fighting an uphill battle of cleanup and rework.
What’s your experience with the Context Crisis?
How are you handling context when working with AI coding tools or agents? What techniques or tools have helped (or failed) in your projects?
Share your practical insights in the comments — this is quickly becoming one of the most important engineering challenges of 2026.

ContextEngineering #AIin2026 #DeveloperProductivity #AIDevelopment #SoftwareEngineering #ContextCrisis #DevCommunity

Ports and Adapters: The Pattern Your Architecture Has Been Missing

In the last post you counted your OrderService‘s external dependencies. If you got anything higher than zero, this post is for you.

We named the problem. Now let’s name the solution.

It Has a Name

The pattern is called ports and adapters also known as hexagonal architecture, coined by Alistair Cockburn in 2005. The name has stuck around because the idea is genuinely useful: your application core should communicate with the outside world through well-defined boundaries, not direct dependencies.

That’s the theory. Here’s what it actually means in code.

What a Port Is

A port is an interface owned by your domain. It says: “I need something that can do X. I don’t care how.”

from typing import Protocol, Optional
from app.domain.models import Order, Customer

class CustomerRepository(Protocol):
    def find_by_id(self, customer_id: str) -> Optional[Customer]:
        ...

class OrderRepository(Protocol):
    def save(self, order: Order) -> Order:
        ...

Notice what these interfaces don’t mention: SQLAlchemy, PostgreSQL, sessions, ORM models. They speak the language of your domain — Customer, Order not the language of your database.

This is the port. It’s the socket in your domain that infrastructure plugs into.

What an Adapter Is

An adapter is the infrastructure implementation of a port. It’s the plug.

from sqlalchemy.orm import Session
from app.domain.ports import CustomerRepository, OrderRepository
from app.domain.models import Customer, Order
from app import orm

class SQLAlchemyCustomerRepository:
    def __init__(self, session: Session):
        self.session = session

    def find_by_id(self, customer_id: str) -> Optional[Customer]:
        row = self.session.query(orm.CustomerRow).filter_by(id=customer_id).first()
        if not row:
            return None
        return Customer(
            id=row.id,
            loyalty_points=row.loyalty_points
        )

class SQLAlchemyOrderRepository:
    def __init__(self, session: Session):
        self.session = session

    def save(self, order: Order) -> Order:
        row = orm.OrderRow(
            customer_id=order.customer_id,
            total=order.total,
            status=order.status
        )
        self.session.add(row)
        self.session.commit()
        self.session.refresh(row)
        order.id = row.id
        return order

SQLAlchemy lives here. The ORM mapping lives here. The session.commit() lives here. Your domain doesn’t see any of it.

The Before/After

Here’s the OrderService from Post 1 the one that knew too much:

class OrderService:
    def place_order(self, customer_id: int, items: list, db: Session):
        customer = db.query(Customer).filter(Customer.id == customer_id).first()
        if not customer:
            raise HTTPException(status_code=404, detail="Customer not found")

        total = sum(item["price"] * item["qty"] for item in items)
        if customer.loyalty_points > 500:
            total *= 0.9

        order = Order(customer_id=customer_id, total=total, status="pending", items=items)
        db.add(order)
        db.commit()
        db.refresh(order)
        return {"order_id": order.id, "total": total, "status": "pending"}

Here’s the same service after the refactor:

from app.domain.ports import CustomerRepository, OrderRepository
from app.domain.models import Order, OrderItem

class OrderService:
    def __init__(
        self,
        customer_repo: CustomerRepository,
        order_repo: OrderRepository,
    ):
        self.customer_repo = customer_repo
        self.order_repo = order_repo

    def place_order(self, customer_id: str, items: list[OrderItem]) -> Order:
        customer = self.customer_repo.find_by_id(customer_id)
        if not customer:
            raise ValueError(f"Customer {customer_id} not found")

        order = Order(customer_id=customer_id, items=items, loyalty_points=customer.loyalty_points)
        order.total = order.calculate_total()
        order.status = "pending"

        return self.order_repo.save(order)

What changed:

  • No db: Session parameter. The service doesn’t know a database exists.
  • No HTTPException. That’s the API layer’s job, not the domain’s.
  • No ORM models. Order and Customer are plain domain objects.
  • The dependencies come in through __init__ the service declares what it needs without knowing how it’s provided.

Now Try to Test It

class InMemoryCustomerRepository:
    def __init__(self, customers: dict):
        self.customers = customers

    def find_by_id(self, customer_id: str) -> Optional[Customer]:
        return self.customers.get(customer_id)

class InMemoryOrderRepository:
    def __init__(self):
        self.saved = []

    def save(self, order: Order) -> Order:
        order.id = f"order-{len(self.saved) + 1}"
        self.saved.append(order)
        return order


def test_loyalty_discount_applied():
    customer_repo = InMemoryCustomerRepository({
        "c-1": Customer(id="c-1", loyalty_points=600)
    })
    order_repo = InMemoryOrderRepository()
    service = OrderService(customer_repo, order_repo)

    result = service.place_order("c-1", [OrderItem("p-1", 100.0, 2)])

    assert result.total == 180.0
    assert result.status == "pending"

No database. No HTTP framework. No environment variables. The test runs in milliseconds and covers exactly what it claims to cover.

This is the payoff.

The Direction of Dependency

Here’s the rule that makes this work: dependencies point inward.

FastAPI route → OrderService → CustomerRepository (port)
                                      ↑
                     SQLAlchemyCustomerRepository (adapter) ← FastAPI route wires this in

The domain defines the port. The adapter implements it. The wiring happens at the edges in your FastAPI startup, your dependency injection container, wherever your app is assembled. The domain never reaches out to the infrastructure. The infrastructure reaches in to fulfill the domain’s contracts.

This is the inversion of control at the heart of the pattern.

What You Get

Swappable infrastructure. Want to test against an in-memory store? Swap the adapter. Migrating from PostgreSQL to another database? Write a new adapter. The domain doesn’t notice.

Testable business logic. No fixtures. No Docker containers in unit tests. The domain logic tests itself.

Explicit boundaries. Every time someone wants to add a database call to the service layer, they have to go through the port. The port is a checkpoint. It forces the question: is this a domain concern, or infrastructure?

One Thing to Watch Out For

Ports should be defined by what the domain needs, not by what the database offers. A port that looks like this is a red flag:

class OrderRepository(Protocol):
    def execute_raw_sql(self, query: str) -> list:
        ...

That’s an infrastructure interface wearing a domain name. The domain shouldn’t know about SQL. Keep ports at the level of domain operations: find_by_id, save, find_pending_orders. If you can read the method name and understand the business intent without knowing anything about databases, you’re in the right place.

What’s Next

You now have the pattern. Ports declare the need. Adapters fulfill it. The domain stays clean.

But ports and adapters only work if you have a domain worth protecting. If your domain objects are just bags of getters and setters no behavior, no rules, no real logic the boundaries don’t buy you much.

The next post is about fixing that. We’re going to build a domain model that actually models the domain: real behavior on real objects, not data containers with a fancy name.

This is Post 2 of 5 in the Hexagonal Architecture series.

Beyond the Haversine Formula: Why I Use Geohashing for Spatial Search

TL;DR: Geohashing encodes 2D coordinates into hierarchical string prefixes, transforming expensive O(n) geometric calculations into efficient indexed lookups. By mapping geographic areas to unique string identifiers, databases can execute high-speed prefix scans rather than performing floating-point evaluations on every record. This allows applications to scale proximity searches to millions of concurrent users without hitting CPU bottlenecks.

I have seen too many backends crawl to a halt because they are trying to solve geometry problems at the query layer. The naive approach to finding a nearby taxi or a local restaurant is to store latitude and longitude as floats and then run a radius query. While this works in a development environment with a hundred rows, it fails at production scale because it forces the database to perform an unindexed geometric predicate on every single record.

When I am architecting a system that needs to handle thousands of concurrent spatial queries, I stop asking the database to do trigonometry. Instead, I treat location as a string matching problem. By moving the complexity from the CPU to the index, I can keep response times low even as the dataset grows into the millions.

Why is calculating distance in a database expensive?

Proximity is not a property that standard B-Tree indexes can efficiently filter without specialized spatial extensions. This usually forces the database engine to perform an expensive floating-point evaluation on every record in the table to determine if a point falls within the search radius.

In a standard relational database, an index is great for finding an exact match or a range of numbers. But a radius is a circle, and latitude/longitude are two independent variables. To find objects in that circle, the database has to calculate the distance between your center point and every potential candidate. If I have 100,000 drivers and 1,000 users searching at once, the CPU is effectively pinned just trying to solve high-school geometry millions of times per second. It simply does not scale.

How does Geohashing solve the spatial indexing problem?

Geohashing encodes latitude and longitude into a single string by recursively partitioning the map into a grid. This maps 2D spatial data onto a 1D string, where points that are physically close share the same character prefix, allowing the database to bucket locations together.

I think of it as a recursive subdivision of the world. If I split the map into a grid and label a large square ‘B’, any point inside that square starts with the letter ‘B’. If I divide ‘B’ into smaller squares and label one ‘C’, any point in that smaller square now has the prefix ‘BC’. As I continue this process, I build a hierarchical prefix tree. A six-character geohash represents a specific neighborhood, while an eight-character hash points to a specific street corner.

Geohash Length Approximate Area Coverage Engineering Use Case
1 5,000km x 5,000km Global data sharding
4 39km x 19km Regional search / Weather
6 1.2km x 0.6km Local delivery / Dispatching
8 38m x 19m Precise asset tracking

Why is prefix matching better than radius math?

Prefix matching turns a complex spatial calculation into a simple index range scan. By querying for a specific string prefix, I am leveraging the database’s primary or secondary index to find nearby points in logarithmic time rather than linear time.

When I use geohashes, I am no longer asking the database to calculate distances. I am asking it to find every record where the location_hash starts with a specific string, like bcde. This is an operation that every modern database, from PostgreSQL to DynamoDB, is built to do at high speed. It essentially turns a spatial query into a standard B-Tree lookup, which is significantly cheaper on the CPU than executing the Haversine formula across the entire dataset.

How do you handle points on the edge of a grid?

I handle the “edge case”—where two people are physically close but separated by an arbitrary grid line—by querying the user’s current square plus its eight immediate neighbors. This ensures complete coverage without sacrificing the performance gains of the indexed lookup.

While querying nine squares sounds like more work than querying one, it is still orders of magnitude faster than a full table scan. Most geohashing libraries provide a simple function to calculate these “neighboring” hashes. By fetching these nine prefixes in a single batch, I can guarantee that I never miss a nearby taxi just because it happens to be across the street in a different grid cell.

FAQ

Can I use Geohashing with NoSQL databases like DynamoDB?
Yes, this is a primary use case for Geohashing. Since DynamoDB doesn’t have native spatial types, you can store the geohash as a Sort Key to perform efficient prefix scans, which is the only way to do performant “nearby” searches in most NoSQL environments.

How do I decide the length of the geohash to store?
I usually store at a high precision (10-12 characters) but query at a lower precision. For a ride-sharing app, I might query at length 6 to get a 1km search area, then do a quick client-side sort to find the absolute closest driver from that filtered subset.

Is Geohashing better than PostGIS?
PostGIS is excellent for complex polygons and precise geographic analysis. However, if your only goal is to find “points near me” at massive scale, Geohashing is often easier to implement, cheaper to run, and more portable across different database technologies.**

What Actually Happens in the 2 Seconds After You Hit Enter

You type “google.com” and press Enter. A page appears. Feels instant. But in that blink — roughly 2 seconds — your browser just orchestrated a relay race across dozens of machines spanning multiple continents.

I find it genuinely wild that most web developers ship code every day without knowing what happens between keystroke and pixel. So here’s the full chain, no hand-waving.

Step 1: DNS — Translating Names to Numbers

Your browser doesn’t know what “google.com” means. Computers speak IP addresses, not words. So the first job is translation.

The browser checks its own cache first. Then the OS cache. Then your router’s cache. If nobody has the answer, the query goes to a recursive DNS resolver — usually run by your ISP or a service like Cloudflare (1.1.1.1) or Google (8.8.8.8).

That resolver walks the DNS hierarchy: root server → .com TLD server → Google’s authoritative nameserver. Each step narrows down until someone says “google.com lives at 142.250.70.14.” The whole lookup typically takes 20-120 milliseconds.

Fun fact: there are only 13 root server addresses in the entire DNS system. They handle billions of queries daily through anycast routing — the same IP address served from hundreds of physical locations worldwide.

Step 2: TCP — The Three-Way Handshake

Now your browser knows where to go. But before sending any data, it needs a reliable connection. That means TCP.

TCP uses a three-way handshake:

  1. SYN — your browser says “I want to talk”
  2. SYN-ACK — the server replies “acknowledged, let’s go”
  3. ACK — your browser confirms “we’re connected”

Three packets, just to say hello. This adds another round-trip of latency — typically 10-50ms for a nearby server, more for distant ones.

Step 3: TLS — Encrypting Everything

If the site uses HTTPS (and 95%+ of the web does now), there’s another handshake on top of TCP. TLS negotiation involves:

  • Your browser sending supported cipher suites
  • The server picking one and sending its certificate
  • Your browser verifying that certificate against trusted Certificate Authorities
  • Both sides generating session keys for encryption

TLS 1.3 streamlined this to a single round-trip. Older TLS 1.2 needed two. Either way, every byte after this point is encrypted. Nobody between you and the server — not your ISP, not the coffee shop WiFi owner — can read the content.

Step 4: HTTP — The Actual Request

Finally, your browser sends the HTTP request: GET / HTTP/2. The server processes it, pulls the HTML, and sends it back. Modern HTTP/2 multiplexes multiple requests over a single connection, so your browser can fetch HTML, CSS, JavaScript, and images simultaneously instead of queuing them up one by one.

Step 5: Rendering — Turning Code into Pixels

The browser parses HTML into a DOM tree, CSS into a CSSOM tree, merges them into a render tree, calculates layout (where everything goes on screen), and paints pixels. JavaScript can interrupt this entire process, which is why a badly-placed script tag can freeze your page.

Chrome’s rendering engine (Blink) does all of this in under 100ms for a typical page. The entire journey — DNS, TCP, TLS, HTTP, render — happens in about 1-2 seconds. Often less.

Why This Matters

Understanding this chain isn’t just trivia. It’s how you debug real problems. Slow TTFB? Probably server-side. Slow page load with fast TTFB? Look at render-blocking resources. Random timeouts? Could be DNS or TLS certificate issues.

Every performance optimization targets one of these steps. CDNs shorten the physical distance (faster TCP). DNS prefetching eliminates lookup time. HTTP/2 push sends assets before the browser asks. Code splitting reduces what the browser needs to parse.

Two seconds. Dozens of machines. Billions of times a day. The internet is absurdly complex — we’ve just gotten really good at hiding it.

AI Personalisation Reshapes Fashion

Tim Green

Stand in front of your phone camera, and within seconds, you’re wearing a dozen different lipstick shades you’ve never touched. Tilt your head, and the eyeglasses perched on your digital nose move with you, adjusting for the light filtering through the acetate frames. Ask a conversational AI what to wear to a summer wedding, and it curates an entire outfit based on your past purchases, body measurements, and the weather forecast for that day.

This isn’t science fiction. It’s Tuesday afternoon shopping in 2025, where artificial intelligence has transformed the fashion and lifestyle industries from guesswork into a precision science. The global AI in fashion market, valued at USD 1.99 billion in 2024, is projected to explode to USD 39.71 billion by 2033, growing at a staggering 39.43% compound annual growth rate. The beauty industry is experiencing a similar revolution, with AI’s market presence expected to reach $16.3 billion by 2026, growing at 25.4% annually since 2021.

But as these digital advisors become more sophisticated, they’re raising urgent questions about user experience design, data privacy, algorithmic bias, and consumer trust. Which sectors will monetise these technologies first? What safeguards are essential to prevent these tools from reinforcing harmful stereotypes or invading privacy? And perhaps most critically, as AI learns to predict our preferences with uncanny accuracy, are we being served or manipulated?

The Personalisation Arms Race

The transformation began quietly. Stitch Fix, the online personal styling service, has been using machine learning since its inception, employing what it calls a human-AI collaboration model. The system doesn’t make recommendations directly to customers. Instead, it arms human stylists with data-driven insights, analysing billions of data points on clients’ fit and style preferences. According to the company, AI and machine learning are “pervasive in every facet of the function of the company, whether that be merchandising, marketing, finance, obviously our core product of recommendations and styling.”

In 2025, Stitch Fix unveiled Vision, a generative AI-powered tool that creates personalised images showing clients styled in fresh outfits. Now in beta, Vision generates imagery of a client’s likeness in shoppable outfit recommendations based on their style profile and the latest fashion trends. The company also launched an AI Style Assistant that engages in dialogue with clients, using the extensive data already known about them. The more it’s used, the smarter it gets, learning from every interaction, every thumbs-up and thumbs-down in the Style Shuffle feature, and even images customers engage with on platforms like Pinterest.

But Stitch Fix is hardly alone. The beauty sector has emerged as the testing ground for AI personalisation’s most ambitious experiments. L’Oréal’s acquisition of ModiFace in 2018 marked the first time the cosmetics giant had purchased a tech company, signalling a fundamental shift in how beauty brands view technology. ModiFace’s augmented reality and AI capabilities, created since 2007, now serve nearly a billion consumers worldwide. According to L’Oréal’s 2024 Annual Innovation Report, the ModiFace system allows customers to virtually sample hundreds of lipstick shades with 98% colour accuracy.

The business results have been extraordinary. L’Oréal’s ModiFace virtual try-on technology has tripled e-commerce conversion rates, whilst attracting more than 40 million users in the past year alone. This success is backed by a formidable infrastructure: 4,000 scientists in 20 research centres worldwide, 6,300 digital talents, and 3,200 tech and data experts.

Sephora’s journey illustrates the patience required to perfect these technologies. Before launching Sephora Virtual Artist in partnership with ModiFace, the retailer experimented with augmented reality for five years. By 2018, within two years of launching, Sephora Virtual Artist saw over 200 million shades tried on and over 8.5 million visits to the feature. The platform’s AI algorithms analyse facial geometry, identifying features such as lips, eyes, and cheekbones to apply digital makeup with remarkable precision, adjusting for skin tone and ambient lighting to enhance realism.

The impact on Sephora’s bottom line has been substantial. The AI-powered Virtual Artist has driven a 25% increase in add-to-basket rates and a 35% rise in conversions for online makeup sales. Perhaps more telling, the AR experience increased average app session times from 3 minutes to 12 minutes, with virtual try-ons growing nearly tenfold year-over-year. The company has also cut out-of-stock events by around 30%, reduced inventory holding costs by 20%, and decreased markdown rates on excess stock by 15%.

The Eyewear Advantage

Whilst beauty brands have captured headlines, the eyewear industry has quietly positioned itself as a formidable player in the AI personalisation space. The global eyewear market, valued at USD 200.46 billion in 2024, is projected to reach USD 335.90 billion by 2030, growing at 8.6% annually. But it’s the integration of AI and AR technologies that’s transforming the sector’s growth trajectory.

Warby Parker’s co-founder and co-CEO Dave Gilboa explained that virtual try-on has been part of the company’s long-term plan since it launched. “We’ve been patiently waiting for technology to catch up with our vision for what that experience could look like,” he noted. Co-founder Neil Blumenthal emphasised they didn’t want their use of AR to feel gimmicky: “Until we were able to have a one-to-one reference and have our glasses be true to scale and fit properly on somebody’s face, none of the tools available were functional.”

The breakthrough came when Apple released its iPhone X with its TrueDepth camera. Warby Parker developed its virtual try-on feature using Apple’s ARKit, creating what the company describes as a “placement algorithm that mimics the real-life process of placing a pair of frames on your face, taking into account how your unique facial features interact with the frame.” The glasses stay fixed in place if you tilt your head and even show how light filters through acetate frames.

The strategic benefits extend beyond customer experience. Warby Parker already offered a home try-on programme, but the AR feature delivers a more immediate experience whilst potentially saving the retailer time and money associated with logistics. More significantly, offering a true-to-life virtual try-on option minimises the number of frames being shipped to consumers and reduces returns.

The eyewear sector’s e-commerce segment is experiencing explosive growth, predicted to witness a CAGR of 13.4% from 2025 to 2033. In July 2025, Lenskart secured USD 600 million in funding to expand its AI-powered online eyewear platform and retail presence in Southeast Asia. In February 2025, EssilorLuxottica unveiled its advanced AI-driven lens customisation platform, enhancing accuracy by up to 30% and reducing production time by 30%.

The smart eyewear segment represents an even more ambitious frontier. Meta’s $3.5 billion investment in EssilorLuxottica illustrates the power of joint venture models. Ray-Ban Meta glasses were the best-selling product in 60% of Ray-Ban’s EMEA stores in Q3 2024. Global shipments of smart glasses rose 110% year-over-year in the first half of 2025, with AI-enabled models representing 78% of shipments, up from 46% the same period the year prior. Analysts expect sales to quadruple in 2026.

The Conversational Commerce Revolution

The next phase of AI personalisation moves beyond visual try-ons to conversational shopping assistants that fundamentally alter the customer relationship. The AI Shopping Assistant Market, valued at USD 3.65 billion in 2024, is expected to reach USD 24.90 billion by 2032, growing at a CAGR of 27.22%. Fashion and apparel retailers are expected to witness the fastest growth rate during this period.

Consumer expectations are driving this shift. According to a 2024 Coveo survey, 72% of consumers now expect their online shopping experiences to evolve with the adoption of generative AI. A December 2024 Capgemini study found that 52% of worldwide consumers prefer chatbots and virtual agents because of their easy access, convenience, responsiveness, and speed.

The numbers tell a dramatic story. Between November 1 and December 31, 2024, traffic from generative AI sources increased by 1,300% year-over-year. On Cyber Monday alone, generative AI traffic was up 1,950% year-over-year. According to a 2025 Adobe survey, 39% of consumers use generative AI for online shopping, with 53% planning to do so this year.

One global lifestyle player developed a gen-AI-powered shopping assistant and saw its conversion rates increase by as much as 20%. Many providers have demonstrated increases in customer basket sizes and higher margins from cross-selling. For instance, 35up, a platform that optimises product pairings for merchants, reported an 11% increase in basket size and a 40% rise in cross-selling margins.

Natural Language Processing dominated the AI shopping assistant technology segment with 45.6% market share in 2024, reflecting its importance in enabling conversational product search, personalised guidance, and intent-based shopping experiences. According to a recent study by IMRG and Hive, three-quarters of fashion retailers plan to invest in AI over the next 24 months.

These conversational systems work by combining multiple AI technologies. They use natural language understanding to interpret customer queries, drawing on vast product databases and customer history to generate contextually relevant responses. The most sophisticated implementations can understand nuance—distinguishing between “I need something professional for an interview” and “I want something smart-casual for a networking event”—and factor in variables like climate, occasion, personal style preferences, and budget constraints simultaneously.

The personalisation extends beyond product recommendations. Advanced conversational AI can remember past interactions, track evolving preferences, and even anticipate needs based on seasonal changes or life events mentioned in previous conversations. Some systems integrate with calendar applications to suggest outfits for upcoming events, or connect with weather APIs to recommend appropriate clothing based on forecasted conditions.

However, these capabilities introduce new complexities around data integration and privacy. Each additional data source—calendar access, location information, purchase history from multiple retailers—creates another potential vulnerability. The systems must balance comprehensive personalisation with respect for data boundaries, offering users granular control over what information the AI can access.

The potential value is staggering. If adoption follows a trajectory similar to mobile commerce in the 2010s, agentic commerce could reach $3-5 trillion in value by 2030. But this shift comes with risks. As shoppers move from apps and websites to AI agents, fashion players risk losing ownership of the consumer relationship. Going forward, brands may need to pay for premium integration and placement in agent recommendations, fundamentally altering the economics of digital retail.

Yet even as these technologies promise unprecedented personalisation and convenience, they collide with a fundamental problem that threatens to derail the entire revolution: consumer trust.

The Trust Deficit

For all their sophistication, AI personalisation tools face a fundamental challenge. The technology’s effectiveness depends on collecting and analysing vast amounts of personal data, but consumers are increasingly wary of how companies use their information. A Pew Research study found that 79% of consumers are concerned about how companies use their data, fuelling demand for greater transparency and control over personal information.

The beauty industry faces particular scrutiny. A survey conducted by FIT CFMM found that over 60% of respondents are aware of biases in AI-driven beauty tools, and nearly a quarter have personally experienced them. These biases aren’t merely inconvenient; they can reinforce harmful stereotypes and exclude entire demographic groups from personalised recommendations.

The manifestations of bias are diverse and often subtle. Recommendation algorithms might consistently suggest lighter foundation shades to users with darker skin tones, or fail to recognise facial features accurately across different ethnic backgrounds. Virtual try-on tools trained primarily on Caucasian faces may render makeup incorrectly on Asian or African facial structures. Size recommendation systems might perpetuate narrow beauty standards by suggesting smaller sizes regardless of actual body measurements.

These problems often emerge from the intersection of insufficient training data and unconscious human bias in algorithm design. When development teams lack diversity, they may not recognise edge cases that affect underrepresented groups. When training datasets over-sample certain demographics, the resulting AI inherits and amplifies those imbalances.

In many cases, the designers of algorithms do not have ill intentions. Rather, the design and the data can lead artificial intelligence to unwittingly reinforce bias. The root cause usually goes to input data, tainted with prejudice, extremism, harassment, or discrimination. Combined with a careless approach to privacy and aggressive advertising practices, data can become the raw material for a terrible customer experience.

AI systems may inherit biases from their training data, resulting in inaccurate or unfair outcomes, particularly in areas like sizing, representation, and product recommendations. Most training datasets aren’t curated for diversity. Instead, they reflect cultural, gender, and racial biases embedded in online images. The AI doesn’t know better; it just replicates what it sees most.

The Spanish fashion retailer Mango provides a cautionary tale. The company rolled out AI-generated campaigns promoting its teen lines, but its models were uniformly hyper-perfect: all fair-skinned, full-lipped, and fat-free. Diversity and inclusivity didn’t appear to be priorities, illustrating how AI can amplify existing industry biases when not carefully monitored.

Consumer awareness of these issues is growing rapidly. A 2024 survey found that 68% of consumers would switch brands if they discovered AI-driven personalisation was systematically biased. The reputational risk extends beyond immediate sales impact; brands associated with discriminatory AI face lasting damage to their market position and social licence to operate.

Building Better Systems

The good news is that the industry increasingly recognises these challenges and is developing solutions. USC computer science researchers proposed a novel approach to mitigate bias in machine learning model training, published at the 2024 AAAI Conference on Artificial Intelligence. The researchers used “quality-diversity algorithms” to create diverse synthetic datasets that strategically “plug the gaps” in real-world training data. Using this method, the team generated a diverse dataset of around 50,000 images in 17 hours, testing on measures of diversity including skin tone, gender presentation, age, and hair length.

Various approaches have been proposed to mitigate bias, including dataset augmentation, bias-aware algorithms that consider different types of bias, and user feedback mechanisms to help identify and correct biases. Priti Mhatre from Hogarth advocates for bias mitigation techniques like adversarial debiasing, “where two models, one as a classifier to predict the task and the other as an adversary to exploit a bias, can help programme the bias out of the AI-generated content.”

Technical approaches include using Generative Adversarial Networks (GANs) to increase demographic diversity by transferring multiple demographic attributes to images in a biased set. Pre-processing techniques like Synthetic Minority Oversampling Technique (SMOTE) and Data Augmentation have shown promise. In-processing methods modify AI training processes to incorporate fairness constraints, with adversarial debiasing training AI models to minimise both classification errors and biases simultaneously.

Beyond technical fixes, organisational approaches matter equally. Leading companies now conduct regular fairness audits of their AI systems, testing outputs across demographic categories to identify disparate impacts. Some have established external advisory boards comprising ethicists, social scientists, and community representatives to provide oversight on AI development and deployment.

The most effective solutions combine technical and human elements. Automated bias detection tools can flag potential issues, but human judgment remains essential for understanding context and determining appropriate responses. Some organisations employ “red teams” whose explicit role is to probe AI systems for failure modes, including bias manifestations across different user populations.

Hogarth has observed that “having truly diverse talent across AI-practitioners, developers and data scientists naturally neutralises the biases stemming from model training, algorithms and user prompting.” This points to a crucial insight: technical solutions alone aren’t sufficient. The teams building these systems must reflect the diversity of their intended users.

Industry leaders are also investing in bias mitigation infrastructure. This includes creating standardised benchmarks for measuring fairness across demographic categories, developing shared datasets that represent diverse populations, and establishing best practices for inclusive AI development. Several consortia have emerged to coordinate these efforts across companies, recognising that systemic bias requires collective action to address effectively.

The Privacy-Personalisation Paradox

Handling customer data raises significant privacy issues, making consumers wary of how their information is used and stored. Fashion retailers must comply with regulations like the General Data Protection Regulation (GDPR) in the European Union and the California Consumer Privacy Act (CCPA) in the United States, which dictate how personal data must be handled.

The GDPR sets clear rules for using personal data in AI systems, including transparency requirements, data minimisation, and the right to opt-out of automated decisions. The CCPA grants consumers similar rights, including the right to know what data is collected, the right to delete personal data, and the right to opt out of data sales. However, consent requirements differ: the CCPA requires opt-out consent for the sale of personal data, whilst the GDPR requires explicit opt-in consent for processing personal data.

The penalties for non-compliance are severe. The CCPA is enforced by the California Attorney General with a maximum fine of $7,500 per violation. The GDPR is enforced by national data protection authorities with a maximum fine of up to 4% of global annual revenue or €20 million, whichever is higher.

The California Privacy Rights Act (CPRA), passed in 2020, amended the CCPA in several important ways, creating the California Privacy Protection Agency (CPPA) and giving it authority to issue regulations concerning consumers’ rights to access information about and opt out of automated decisions. The future promises even greater scrutiny, with heightened focus on AI and machine learning technologies, enhanced consumer rights, and stricter enforcement.

The practical challenges of compliance are substantial. AI personalisation systems often involve complex data flows across multiple systems, third-party integrations, and international boundaries. Each data transfer represents a potential compliance risk, requiring careful mapping and management. Companies must maintain detailed records of what data is collected, how it’s used, where it’s stored, and who has access—requirements that can be difficult to satisfy when dealing with sophisticated AI systems that make autonomous decisions about data usage.

Moreover, the “right to explanation” provisions in GDPR create particular challenges for AI systems. If a customer asks why they received a particular recommendation, companies must be able to provide a meaningful explanation—difficult when recommendations emerge from complex neural networks processing thousands of variables. This has driven development of more interpretable AI architectures and better logging of decision-making processes.

Forward-thinking brands are addressing privacy concerns by shifting from third-party cookies to zero-party and first-party data strategies. Zero-party data, first introduced by Forrester Research, refers to “data that a customer intentionally and proactively shares with a brand.” What makes it unique is the intentional sharing. Customers know exactly what they’re giving you and expect value in return, creating a transparent exchange that delivers accurate insights whilst building genuine trust.

First-party data, by contrast, is the behavioural and transactional information collected directly as customers interact with a brand, both online and offline. Unlike zero-party data, which customers intentionally hand over, first-party data is gathered through analytics and tracking as people naturally engage with channels.

The era of third-party cookies is coming to a close, pushing marketers to rethink how they collect and use customer data. With browsers phasing out tracking capabilities and privacy regulations growing stricter, the focus has shifted to owned data sources that respect privacy whilst still powering personalisation at scale.

Sephora exemplifies this approach. The company uses quizzes to learn about skin type, colour preferences, and beauty goals. Customers enjoy the experience whilst the brand gains detailed zero-party data. Sephora’s Beauty Insider programme encourages customers to share information about their skin type, beauty habits, and preferences in exchange for personalised recommendations.

The primary advantage of zero-party data is its accuracy and the clear consent provided by customers, minimising privacy concerns and allowing brands to move forward with confidence that the experiences they serve will resonate. Zero-party and first-party data complement each other beautifully. When brands combine what customers say with how they behave, they unlock a full 360-degree view that makes personalisation sharper, campaigns smarter, and marketing far more effective.

Designing for Explainability

Beyond privacy protections, building trust requires making AI systems understandable. Transparent AI means building systems that show how they work, why they make decisions, and give users control over those processes. This is essential for ethical AI because trust depends on clarity; users need to know what’s happening behind the scenes.

Transparency in AI depends on three crucial elements: visibility (revealing what the AI is doing), explainability (clearly communicating why decisions are made), and accountability (allowing users to understand and influence outcomes). Fashion recommendation systems powered by AI have transformed how consumers discover clothing and accessories, but these systems often lack transparency, leaving users in the dark about why certain recommendations are made.

The integration of explainable AI (xAI) techniques amplifies recommendation accuracy. When integrated with xAI techniques like SHAP or LIME, deep learning models become more interpretable. This means that users not only receive fashion recommendations tailored to their preferences but also gain insights into why these recommendations are made. These explanations enhance user trust and satisfaction, making the fashion recommendation system not just effective but also transparent and user-friendly.

Research analysing responses from 224 participants reveals that AI exposure, attitude toward AI, and AI accuracy perception significantly enhance brand trust, which in turn positively impacts purchasing decisions. This study focused on Generation Z’s consumer behaviours across fashion, technology, beauty, and education sectors.

However, in a McKinsey survey of the state of AI in 2024, 40% of respondents identified explainability as a key risk in adopting generative AI. Yet at the same time, only 17% said they were currently working to mitigate it, suggesting a significant gap between recognition and action. To capture the full potential value of AI, organisations need to build trust. Trust is the foundation for adoption of AI-powered products and services.

Research results have indicated significant improvements in the precision of recommendations when incorporating explainability techniques. For example, there was a 3% increase in recommendation precision when these methods were applied. Transparency features, such as explaining why certain products are recommended, and cultural sensitivity in algorithm design can further enhance customer trust and acceptance.

Key practices include giving users control over AI-driven features, offering manual alternatives where appropriate, and ensuring users can easily change personalisation settings. Designing for trust is no longer optional; it is fundamental to the success of AI-powered platforms. By prioritising transparency, privacy, fairness, control, and empathy, designers can create experiences that users not only adopt but also embrace with confidence.

Who Wins the Monetisation Race?

Given the technological sophistication, consumer adoption rates, and return on investment across different verticals, which sectors are most likely to monetise AI personalisation advisors first? The evidence points to beauty leading the pack, followed closely by eyewear, with broader fashion retail trailing behind.

Beauty brands have demonstrated the strongest monetisation metrics. By embracing beauty technology like AR and AI, brands can enhance their online shopping experiences through interactive virtual try-on and personalised product matching solutions, with a proven 2-3x increase in conversions compared to traditional shopping online. Sephora’s use of machine learning to track behaviour and preferences has led to a six-fold increase in ROI.

Brand-specific results are even more impressive. Olay’s Skin Advisor doubled its conversion rates globally. Avon’s adoption of AI and AR technologies boosted conversion rates by 320% and increased order values by 33%. AI-powered data monetisation strategies can increase revenue opportunities by 20%, whilst brands leveraging AI-driven consumer insights experience a 30% higher return on ad spend.

Consumer adoption in beauty is also accelerating rapidly. According to Euromonitor International’s 2024 Beauty Survey, 67% of global consumers now prefer virtual try-on experiences before purchasing cosmetics, up from just 23% in 2019. This dramatic shift in consumer behaviour creates a virtuous cycle: higher adoption drives more data, which improves AI accuracy, which drives even higher adoption.

The beauty sector’s competitive dynamics further accelerate monetisation. With relatively low barriers to trying new products and high purchase frequency, beauty consumers engage with AI tools more often than consumers in other categories. This generates more data, faster iteration cycles, and quicker optimisation of AI models. The emotional connection consumers have with beauty products also drives willingness to share personal information in exchange for better recommendations.

The market structure matters too. Beauty retail is increasingly dominated by specialised retailers like Sephora and Ulta, and major brands like L’Oréal and Estée Lauder, all of which have made substantial AI investments. This concentration of resources in relatively few players enables the capital-intensive R&D required for cutting-edge AI personalisation. Smaller brands can leverage platform solutions from providers like ModiFace, creating an ecosystem that accelerates overall adoption.

The eyewear sector follows closely behind beauty in monetisation potential. Research shows retailers who use AI and AR achieve a 20% higher engagement rate, with revenue per visit growing by 21% and average order value increasing by 13%. Companies can achieve up to 30% lower returns because augmented reality try-on helps buyers purchase items that fit.

Deloitte highlighted that retailers using AR and AI see a 40% increase in conversion rates and a 20% increase in average order value compared to those not using these technologies. The eyewear sector benefits from several unique advantages. The category is inherently suited to virtual try-on; eyeglasses sit on a fixed part of the face, making AR visualisation more straightforward than clothing, which must account for body shape, movement, and fabric drape.

Additionally, eyewear purchases are relatively high-consideration decisions with strong emotional components. Consumers want to see how frames look from multiple angles and in different lighting conditions, making AI-powered visualisation particularly valuable. The sector’s strong margins can support the infrastructure investment required for sophisticated AI systems, whilst the relatively limited SKU count makes data management more tractable.

The strategic positioning of major eyewear players also matters. Companies like EssilorLuxottica and Warby Parker have vertically integrated operations spanning manufacturing, retail, and increasingly, technology development. This control over the entire value chain enables seamless integration of AI capabilities and capture of the full value they create. The partnerships between eyewear companies and tech giants—exemplified by Meta’s investment in EssilorLuxottica—bring resources and expertise that smaller players cannot match.

Broader fashion retail faces more complex challenges. Whilst 39% of cosmetic companies leverage AI to offer personalised product recommendations, leading to a 52% increase in repeat purchases and a 41% rise in customer engagement, fashion retail’s adoption rates remain lower.

McKinsey’s analysis suggests that the global beauty industry is expected to see AI-driven tools influence up to 70% of customer interactions by 2027. The global market for AI in the beauty industry is projected to reach $13.4 billion by 2030, growing at a compound annual growth rate of 20.6% from 2023 to 2030.

With generative AI, beauty brands can create hyper-personalised marketing messages, which could improve conversion rates by up to 40%. In 2025, artificial intelligence is making beauty shopping more personal than ever, with AI-powered recommendations helping brands tailor product suggestions to each individual, ensuring that customers receive options that match their skin type, tone, and preferences with remarkable accuracy.

The beauty industry also benefits from a crucial psychological factor: the intimacy of the purchase decision. Beauty products are deeply personal, tied to identity, self-expression, and aspiration. This creates higher consumer motivation to engage with personalisation tools and share the data required to make them work. Approximately 75% of consumers trust brands with their beauty data and preferences, a higher rate than in general fashion retail.

Making It Work

AI personalisation in fashion and lifestyle represents more than a technological upgrade; it’s a fundamental restructuring of the relationship between brands and consumers. The technologies that seemed impossible a decade ago, that Warby Parker’s founders patiently waited for, are now not just real but rapidly becoming table stakes.

The essential elements are clear. First, UX design must prioritise transparency and explainability. Users should understand why they’re seeing specific recommendations, how their data is being used, and have meaningful control over both. The integration of xAI techniques isn’t a nice-to-have; it’s fundamental to building trust and ensuring adoption.

Second, privacy protections must be built into the foundation of these systems, not bolted on as an afterthought. The shift from third-party cookies to zero-party and first-party data strategies offers a path forward that respects consumer autonomy whilst enabling personalisation. Compliance with GDPR, CCPA, and emerging regulations should be viewed not as constraints but as frameworks for building sustainable customer relationships.

Third, bias mitigation must be ongoing and systematic. Diverse training datasets, bias-aware algorithms, regular fairness audits, and diverse development teams are all necessary components. The cosmetic and skincare industry’s initiatives embracing diversity and inclusion across traditional protected attributes like skin colour, age, ethnicity, and gender provide models for other sectors.

Fourth, human oversight remains essential. The most successful implementations, like Stitch Fix’s approach, maintain humans in the loop. AI should augment human expertise, not replace it entirely. This ensures that edge cases are handled appropriately, that cultural sensitivity is maintained, and that systems can adapt when they encounter situations outside their training data.

The monetisation race will be won by those who build trust whilst delivering results. Beauty leads because it’s mastered this balance, creating experiences that consumers genuinely want whilst maintaining the guardrails necessary to use personal data responsibly. Eyewear is close behind, benefiting from focused applications and clear value propositions. Broader fashion retail has further to go, but the path forward is clear.

Looking ahead, the fusion of AI, AR, and conversational interfaces will create shopping experiences that feel less like browsing a catalogue and more like consulting with an expert who knows your taste perfectly. AI co-creation will enable consumers to develop custom shades, scents, and textures. Virtual beauty stores will let shoppers walk through aisles, try on looks, and chat with AI stylists. The potential $3-5 trillion value of agentic commerce by 2030 will reshape not just how we shop but who controls the customer relationship.

But this future only arrives if we get the trust equation right. The 79% of consumers concerned about data use, the 60% aware of AI biases in beauty tools, the 40% of executives identifying explainability as a key risk—these aren’t obstacles to overcome through better marketing. They’re signals that consumers are paying attention, that they have legitimate concerns, and that the brands that take those concerns seriously will be the ones still standing when the dust settles.

The mirror that knows you better than you know yourself is already here. The question is whether you can trust what it shows you, who’s watching through it, and whether what you see is a reflection of possibility or merely a projection of algorithms trained on the past. Getting that right isn’t just good ethics. It’s the best business strategy available.

References and Sources

  1. Straits Research. (2024). “AI in Fashion Market Size, Growth, Trends & Share Report by 2033.” Retrieved from https://straitsresearch.com/report/ai-in-fashion-market
  2. Grand View Research. (2024). “Eyewear Market Size, Share & Trends.” Retrieved from https://www.grandviewresearch.com/industry-analysis/eyewear-industry
  3. Precedence Research. (2024). “AI Shopping Assistant Market Size to Hit USD 37.45 Billion by 2034.” Retrieved from https://www.precedenceresearch.com/ai-shopping-assistant-market
  4. Retail Brew. (2023). “How Stitch Fix uses AI to take personalization to the next level.” Retrieved from https://www.retailbrew.com/stories/2023/04/03/how-stitch-fix-uses-ai-to-take-personalization-to-the-next-level
  5. Stitch Fix Newsroom. (2024). “How We’re Revolutionizing Personal Styling with Generative AI.” Retrieved from https://newsroom.stitchfix.com/blog/how-were-revolutionizing-personal-styling-with-generative-ai/
  6. L’Oréal Group. (2024). “Discovering ModiFace.” Retrieved from https://www.loreal.com/en/beauty-science-and-technology/beauty-tech/discovering-modiface/
  7. DigitalDefynd. (2025). “5 Ways Sephora is Using AI [Case Study].” Retrieved from https://digitaldefynd.com/IQ/sephora-using-ai-case-study/
  8. Marketing Dive. (2019). “Warby Parker eyes mobile AR with virtual try-on tool.” Retrieved from https://www.marketingdive.com/news/warby-parker-eyes-mobile-ar-with-virtual-try-on-tool/547668/
  9. Future Market Insights. (2025). “Eyewear Market Size, Demand & Growth 2025 to 2035.” Retrieved from https://www.futuremarketinsights.com/reports/eyewear-market
  10. Business of Fashion. (2024). “Smart Glasses Are Ready for a Breakthrough Year.” Retrieved from https://www.businessoffashion.com/articles/technology/the-state-of-fashion-2026-report-smart-glasses-ai-wearables/
  11. Adobe Business Blog. (2024). “Generative AI-Powered Shopping Rises with Traffic to U.S. Retail Sites.” Retrieved from https://business.adobe.com/blog/generative-ai-powered-shopping-rises-with-traffic-to-retail-sites
  12. Business of Fashion. (2024). “AI’s Transformation of Online Shopping Is Just Getting Started.” Retrieved from https://www.businessoffashion.com/articles/technology/the-state-of-fashion-2026-report-agentic-generative-ai-shopping-commerce/
  13. RetailWire. (2024). “Do retailers have a recommendation bias problem?” Retrieved from https://retailwire.com/discussion/do-retailers-have-a-recommendation-bias-problem/
  14. USC Viterbi School of Engineering. (2024). “Diversifying Data to Beat Bias in AI.” Retrieved from https://viterbischool.usc.edu/news/2024/02/diversifying-data-to-beat-bias/
  15. Springer. (2023). “How artificial intelligence adopts human biases: the case of cosmetic skincare industry.” AI and Ethics. Retrieved from https://link.springer.com/article/10.1007/s43681-023-00378-2
  16. Dialzara. (2024). “CCPA vs GDPR: AI Data Privacy Comparison.” Retrieved from https://dialzara.com/blog/ccpa-vs-gdpr-ai-data-privacy-comparison
  17. IBM. (2024). “What you need to know about the CCPA draft rules on AI and automated decision-making technology.” Retrieved from https://www.ibm.com/think/news/ccpa-ai-automation-regulations
  18. RedTrack. (2025). “Zero-Party Data vs First-Party Data: A Complete Guide for 2025.” Retrieved from https://www.redtrack.io/blog/zero-party-data-vs-first-party-data/
  19. Salesforce. (2024). “What is Zero-Party Data? Definition & Examples.” Retrieved from https://www.salesforce.com/marketing/personalization/zero-party-data/
  20. IJRASET. (2024). “The Role of Explanability in AI-Driven Fashion Recommendation Model – A Review.” Retrieved from https://www.ijraset.com/research-paper/the-role-of-explanability-in-ai-driven-fashion-recommendation-model-a-review
  21. McKinsey & Company. (2024). “Building trust in AI: The role of explainability.” Retrieved from https://www.mckinsey.com/capabilities/quantumblack/our-insights/building-ai-trust-the-key-role-of-explainability
  22. Frontiers in Artificial Intelligence. (2024). “Decoding Gen Z: AI’s influence on brand trust and purchasing behavior.” Retrieved from https://www.frontiersin.org/journals/artificial-intelligence/articles/10.3389/frai.2024.1323512/full
  23. McKinsey & Company. (2024). “How beauty industry players can scale gen AI in 2025.” Retrieved from https://www.mckinsey.com/industries/consumer-packaged-goods/our-insights/how-beauty-players-can-scale-gen-ai-in-2025
  24. SG Analytics. (2024). “Future of AI in Fashion Industry: AI Fashion Trends 2025.” Retrieved from https://www.sganalytics.com/blog/the-future-of-ai-in-fashion-trends-for-2025/
  25. Banuba. (2024). “AR Virtual Try-On Solution for Ecommerce.” Retrieved from https://www.banuba.com/solutions/e-commerce/virtual-try-on

Tim Green

Tim Green
UK-based Systems Theorist & Independent Technology Writer

Tim explores the intersections of artificial intelligence, decentralised cognition, and posthuman ethics. His work, published at smarterarticles.co.uk, challenges dominant narratives of technological progress while proposing interdisciplinary frameworks for collective intelligence and digital stewardship.

His writing has been featured on Ground News and shared by independent researchers across both academic and technological communities.

ORCID: 0009-0002-0156-9795
Email: [email protected]