Skip to content

cost(P3): get_by_email full-table Scan (no email GSI) → email GSI / pointer item #36

Closed

Description

@jjbaumert

Priority: P3 (cost) — Tier 1 #3. Part of the 2026-07-11 DynamoDB query-cost review.

Problem

routes/slash_commands.rs:98 and routes/users.rs:487 → user_repo.get_by_email runs a Scan + filter (SK=PROFILE AND email=:email). There is no email GSI (verified against all 8 existing GSIs), so every email lookup reads the whole table. Not on the login hot path (login keys by OAuth sub via GSI6-external-id), but still a full scan on slash-command handle resolution and the users-by-email endpoint.

Fix

Add an email GSI (email_gsi PK on PROFILE rows), or an EMAIL#<lowercased> → user_id pointer item resolved with a single GetItem.

CRDT impact: none

A new GSI only indexes items carrying its key attribute — scope it to PROFILE rows. The high-churn SNAPSHOT#/UPDATE# yrs rows carry no _gsi attrs, so they aren't indexed and don't pay extra write cost; the GSI backfill runs only over user profiles.

Notes: infra (CDK GSI) + storage + schema-duality; deliberate wire/infra change.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions