Skip to content

Latest commit

Β 

History

45 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🌱 deed

Effortless targeted database seeding for query optimization & performance testing

Key Features β€’ Ideal Workflow β€’ Configuration β€’ Performance

deed.mp4

Why?

  • Optimizing at Scale: Your app is growing and your database is pulling heavy weight. You need realistic volume to continuously benchmark and refine your SQL queries and indexes.
  • Zero Prod Data Access: You don't have access to production databases due to strict compliance, privacy, or security regulations.
  • Realistic Load Testing: You need a quick, painless way to generate massive datasets locally without spending days writing custom seed scripts.

Why not?

  • You already have unrestricted access to a fully populated, compliant production database dump.
  • Your workflow relies entirely on strict double-validation of business logic at the UI/API layer for test data.

πŸ“¦ Installation

# TODO: Not ready for a stable release

πŸ—„οΈ Database Coverage

PostgreSQL

Column Types

Category Status Supported Types
Numeric βœ… int2, int4, int8, numeric, decimal, float4, float8, serial, bigserial
Character βœ… varchar, char, text, bpchar
Boolean βœ… boolean
UUID βœ… uuid
Arrays βœ… text[], int[], etc.
Network βœ… inet, cidr, macaddr, macaddr8
Enum βœ… Custom ENUM types
Date & Time βœ… date, time, timetz, timestamp, timestamptz, interval
JSON ⏳ json, jsonb (Planned)
Binary ⏳ bytea (Planned)
Ranges ⏳ int4range, numrange, tsrange, tstzrange, daterange (Planned)
Full-Text ⏳ tsvector, tsquery (Planned)
Geometric ⏳ point, line, lseg, box, path, polygon, circle (Planned)
Bit Strings ⏳ bit, bit varying (Planned)
Composite ⏳ User-defined composite types (Planned)

Constraints & Modifiers

Constraint / Feature Status Notes / Sub-features
Primary Key βœ… Supported
Not Null βœ… Supported
Unique βœ… Supported
Default Expressions βœ… Supported
Generated Columns βœ… GENERATED AS IDENTITY, GENERATED ALWAYS AS (...) STORED
Simple Foreign Key βœ… Resolved across parent dependencies
Composite Foreign Key ⏳ (Planned)
Self-Referencing FK ⏳ (Planned)
Check Constraints ⏳ (Planned)
Exclusion Constraints ⏳ (Planned)
Timing Modifiers ⏳ DEFERRABLE, INITIALLY DEFERRED / IMMEDIATE (Planned)

πŸš€ Usage

Ideal Workflow

Note

Targeted Ingestion: Because SQL queries and index strategies change alongside your UI/UX features, deed is built for targeted iterationsβ€”not for dumping generic data into your entire schema once and forgetting about it.

  1. Spin up a clean DB container with your latest migrations applied.
  2. Identify target tables involved in the specific query or feature you are optimizing.
  3. Seed mock data into those specific tables (and their required parent dependencies) using deed.
  4. Benchmark & rewrite your SQL queries and indexes against realistic data scales.
  5. Destroy the container and repeat for the next iteration.

Deed Config

To customize how mock data is generated, create a deed.json file in your project directory:

{
  "version": "1",
  "database": {
    "name": "postgres"
  },
  "rules": {
    "ignore_tables": [
      "schema_migrations"
    ],
    "tables": {
      "users": {
        // Row count here overrides the CLI flag for this table
        "count": 200,
        "columns": {
          "username": {
            "type": "regex",
            // Define business logic requirements using RE2-compatible regex
            "pattern": "^[a-zA-Z0-9_-]{3,30}$"
          },
          "password_hash": {
            "type": "regex",
            "pattern": "^\\$2[ayb]\\$[0-9]{2}\\$[A-Za-z0-9./]{53}$"
          }
        }
      },
      "countries": {
        "count": 50
      }
    }
  }
}

Tip

Commit your primary deed.json to Git so your team shares base generator rules. When working locally, copy it over, adjust row counts/patterns as needed, and feed your local config to deed.

Seeding Data

Ingest 1,000,000 rows into the app and users tables (along with any required foreign-key parent dependencies):

deed seed \
  --dsn "postgres://postgres:my_secure_password@127.0.0.1:5433/postgres" \
  --tables=app,users \
  --count=1000000 \
  --config=deed.json

Performance

Ingestion throughput is impacted by four core variables:

  1. Dependency depth (number of parent tables requiring resolved FK relationships).
  2. Column complexity (mix of standard scalars vs. regex/custom types).
  3. Total column count per table.
  4. Database host system specifications.

Summary from test runs

Target Dataset Tables Ingested Total Rows Execution Time
Complex Relational Tree 10 tables 5.00M+ 16.27s
Single Table 1 table 20.00M 60.08s
Massive Flat Ingestion 1 table 67.00M ~1.5m
View Test Run Output

Test 1: 1M rows across 5 root tables (10 total resolved dependencies)

Dependencies for 'proof_verifications'
 
πŸ”— proof_verifications
╰── πŸ”— delivery_proofs
    ╰── πŸ”— shipment_tracking_events
        ╰── πŸ”— shipments
            β”œβ”€β”€ πŸ”— orders
            β”‚   ╰── πŸ”— users
            β”œβ”€β”€ πŸ”— shipping_carriers
            ╰── πŸ”— user_addresses
                β”œβ”€β”€ πŸ”— users
                ╰── πŸ”— countries
                                    
Dependencies for 'system_event_logs'                    
                                    
πŸ”— system_event_logs
                        
Seeding Data (10 tables)
                                  
 countries                     50 / 50      [━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━] 100 %       500000 rows/s  βœ” Done
 users                        200 / 200     [━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━] 100 %        2.00M rows/s  βœ” Done
 orders                       300 / 300     [━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━] 100 %        3.00M rows/s  βœ” Done
 system_event_logs        1000000 / 1000000 [━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━] 100 %       422353 rows/s  βœ” Done
 shipping_carriers        1000000 / 1000000 [━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━] 100 %       306030 rows/s  βœ” Done
 user_addresses           1000000 / 1000000 [━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━] 100 %       248877 rows/s  βœ” Done
 shipments                    100 / 100     [━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━] 100 %        1.00M rows/s  βœ” Done
 shipment_tracking_events 1000000 / 1000000 [━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━] 100 %       392016 rows/s  βœ” Done
 delivery_proofs          1000000 / 1000000 [━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━] 100 %       190499 rows/s  βœ” Done
 proof_verifications          100 / 100     [━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━] 100 %        1.00M rows/s  βœ” Done
                                                           
✨ Ingestion complete across all tables. Took 16.27 seconds
                                                           

Test 2: 20 Million rows in 1 table

                                    
Dependencies for 'system_event_logs'
                        
πŸ”— system_event_logs

Seeding Data (1 tables)
                               
 system_event_logs        20000000 / 20000000 [━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━] 100 %       357122 rows/s  βœ” Done
                                                           
✨ Ingestion complete across all tables. Took 60.08 seconds

Test 3: 67 Million rows in 1 table

Dependencies for 'warehouse_shelf_grid'
                                       
πŸ”— warehouse_shelf_grid
                       
Seeding Data (1 tables)
                       
 warehouse_shelf_grid     67000000 / 67000000 [━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━] 100 %       880227 rows/s  βœ” Done
                                                           
✨ Ingestion complete across all tables. Took 99.01 seconds

About

An intuitive, schema-aware synthetic data seeder for targeted database performance testing & API demos

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Used by

Contributors

Languages