Concepts
Data Model

Data Model

Understanding how Runless stores and processes data helps you get the most out of the platform.

Core Entities

Repository

A GitHub repository connected to Runless.

Repository
├── id (internal UUID)
├── github_repository_id (GitHub's numeric ID)
├── owner (e.g., "acme")
├── repo (e.g., "backend")
├── installation_id (link to GitHub App)
└── created_at, updated_at, removed_at

Workflow

A GitHub Actions workflow file (e.g., .github/workflows/ci.yml).

Workflow
├── id (internal UUID)
├── repository_id (link to repository)
├── github_workflow_id (GitHub's numeric ID)
├── workflow_name (from workflow file)
├── workflow_path (e.g., ".github/workflows/ci.yml")
└── created_at, updated_at

Workflow Run

A single execution of a workflow.

Workflow Run
├── id (internal UUID)
├── workflow_id (link to workflow)
├── github_run_id (GitHub's numeric ID)
├── github_run_attempt (1, 2, 3, etc.)
├── status (queued, in_progress, completed)
├── conclusion (success, failure, cancelled, etc.)
├── started_at, completed_at
├── duration_seconds
├── head_sha, head_branch
├── actor (who triggered)
└── event_type (push, pull_request, etc.)

Data Flow

  1. Webhook received: GitHub sends a webhook when a workflow run starts, progresses, or completes
  2. Queued for processing: The webhook is validated and queued
  3. Worker processes: Background worker fetches additional details if needed
  4. Stored in database: Run data is persisted
  5. Available in UI: Dashboard queries aggregated data

Metrics Calculation

Success Rate

COUNT(CASE WHEN conclusion = 'success') / COUNT(*) * 100

Only counts completed runs (excludes in-progress).

Re-run Rate

COUNT(CASE WHEN github_run_attempt > 1) / COUNT(*) * 100

Counts any run that was a re-run attempt.

Duration Percentiles

PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY duration_seconds)

Uses PostgreSQL's percentile functions on completed runs.

Data Freshness

Data TypeUpdate Frequency
New runsReal-time (webhook)
Run completionReal-time (webhook)
Analytics aggregationOn-demand (query time)
DetectionsPeriodic (background job)

Retention

Data is retained based on your plan:

PlanRun DataAggregates
Free14 days14 days
Team90 days90 days
Pro1 year1 year
EnterpriseCustomCustom

After retention expires:

  • Detailed run records are deleted
  • Aggregated metrics may be preserved for trend analysis

Limitations

Rate Limits

  • Webhook ingestion: No practical limit
  • Historical sync: Respects GitHub API rate limits
  • Dashboard queries: Optimized, but very large teams may see slower loads

Data Volume

  • Individual runs: Unlimited
  • Workflows per repo: Unlimited
  • Repos per team: Unlimited (plan limits on runs/month)