Skip to main content
Lynx uses two related concepts for simulation work: batches and jobs.

Batch

A batch is the top-level unit of submitted work, created by a single POST /jobs call. It represents one Monte Carlo study. A batch has:
  • a unique UUID (batch_id)
  • a name you provide
  • a total job count
  • counters for completed and failed jobs
  • an overall status: Pending, Running, Completed, Failed, or Cancelled
  • a created timestamp
A batch is complete when all its jobs reach a terminal state.

Job

A job is one individual simulation run within a batch, created automatically by Lynx when you submit a batch. Each job gets its own sampled parameter set drawn from the dispersions you defined. A job has:
  • a unique UUID (job_id)
  • a reference to its parent batch_id
  • the sampled parameters for this run (run_config)
  • a status
  • retry tracking: retries, max_retries
  • a timeout: timeout_secs
  • timestamps: created_at, claimed_at, started_at, completed_at
  • the ID of the runner that claimed it: assigned_runner
  • an error message if it failed: error_message

Batch vs job

BatchJob
Created byYour POST /jobs callLynx automatically
GranularityOne studyOne parameter sample
Status endpointGET /batches/{batch_id}GET /jobs/{job_id}
Results endpointGET /batches/{batch_id}/resultsGET /jobs/{job_id}/results
RetriesBatches do not retryJobs retry up to max_retries

Submitting a batch

curl -sS \
  -X POST https://api.lynx.tetryx.io/jobs \
  -H 'content-type: application/json' \
  -d '{
    "name": "spacecraft-analysis-v1",
    "config": {
      "simulation": {
        "name": "Spacecraft Mission Analysis",
        "version": "1.0.0",
        "duration_minutes": 120
      },
      "monte_carlo": {
        "runs": 500,
        "sampling_method": "latin_hypercube",
        "seed": 42
      },
      "dispersions": {
        "mass_kg": {
          "distribution": { "type": "normal", "mean": 2500.0, "std_dev": 125.0 },
          "units": "kg"
        },
        "drag_coefficient": {
          "distribution": { "type": "uniform", "min": 0.28, "max": 0.34 },
          "units": ""
        }
      },
      "compute": {
        "container": {
          "image": "your-org/simulation:latest",
          "cpu_request": "2000m",
          "memory_request": "4Gi"
        },
        "max_parallel_jobs": 20,
        "job_timeout_seconds": 3600
      },
      "early_termination": {
        "enabled": true,
        "check_frequency_hz": 10.0,
        "conditions": [
          {
            "variable": "battery_state_of_charge",
            "condition": "< 0.1",
            "description": "Battery critically low"
          }
        ]
      },
      "telemetry": {
        "sampling_rate_hz": 10.0,
        "variables": ["altitude", "velocity", "battery_state_of_charge"],
        "storage": {
          "s3_bucket": "your-telemetry-bucket",
          "s3_prefix": "spacecraft/",
          "compression": "gzip"
        },
        "buffer_flush_interval_seconds": 30
      }
    }
  }' | jq
Use runs_override to cap the run count without changing your config — useful for quick validation:
{
  "name": "quick-test",
  "runs_override": 3,
  "config": { ... }
}

Monitoring a batch

# Batch status with per-status job counts
curl -s https://api.lynx.tetryx.io/batches/<batch-id> | jq

# All terminal results for the batch
curl -s https://api.lynx.tetryx.io/batches/<batch-id>/results | jq
The status response includes:
  • jobs_by_status — job count for each status (Pending, Running, Completed, Failed, etc.)
  • throughput_jobs_per_minute — current processing rate
  • estimated_completion_time_mins — time remaining estimate, if computable

Sampling methods

MethodDescription
latin_hypercubeStratified sampling — best coverage with fewer runs
monte_carloPure random sampling
quasi_monte_carloLow-discrepancy sequence sampling
Latin Hypercube Sampling (latin_hypercube) is recommended for most studies. It produces better parameter space coverage than random sampling with the same number of runs.