{
  "id": "p2vpspreflight0001",
  "name": "Run a credential-free n8n VPS preflight with 2,500 synthetic items",
  "nodes": [
    {
      "parameters": {
        "content": "## Credential-free VPS preflight\n\nUse this fixed workload before treating a VPS as production-ready.\n\n1. Run the workflow on the candidate n8n instance.\n2. Confirm the final node returns `preflight_pass: true`.\n3. Record total execution time, peak process-tree memory, swap/OOM events, and restart behavior outside this workflow.\n4. Repeat several times and test your own representative workflow before buying or migrating.\n\nThis fixture makes no network calls, uses no credentials, and writes no files. A pass proves only that this bounded synthetic transformation completed. It does **not** prove production capacity, provider quality, uptime, backup integrity, or a universal RAM requirement.\n\nOptional measurement worksheet: https://smallbiz-auto.com/n8n-vps-requirements",
        "height": 410,
        "width": 620,
        "color": 5
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -620,
        -470
      ],
      "id": "4fb7ff52-89c5-4fc0-bdbc-e5dc4fa04bb0",
      "name": "Read me first"
    },
    {
      "parameters": {},
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        -560,
        0
      ],
      "id": "781568b2-3fd7-4c99-a8ff-d4458c9e40d0",
      "name": "Run preflight manually"
    },
    {
      "parameters": {
        "inputSource": "passthrough"
      },
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "typeVersion": 1.1,
      "position": [
        -560,
        140
      ],
      "id": "bd36c5bd-84b7-42f4-86bc-d55cb4a5d976",
      "name": "Run as a sub-workflow"
    },
    {
      "parameters": {
        "jsCode": "const config = { item_count: 2500, bucket_count: 20, payload_chars: 128 };\nconst startedAtMs = Date.now();\nconst payload = 'x'.repeat(config.payload_chars);\nreturn Array.from({ length: config.item_count }, (_, index) => {\n  const id = index + 1;\n  return { json: {\n    id,\n    amount: (id % 100) + 1,\n    bucket: `b${id % config.bucket_count}`,\n    label: `synthetic-${id}`,\n    payload,\n    started_at_ms: startedAtMs\n  } };\n});"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -300,
        0
      ],
      "id": "7d22534c-803e-44ed-af12-c522d80c3a57",
      "name": "Generate bounded synthetic items"
    },
    {
      "parameters": {
        "jsCode": "return $input.all().map((item) => ({ json: {\n  id: Number(item.json.id),\n  amount: Number(item.json.amount),\n  bucket: String(item.json.bucket).toUpperCase(),\n  label_length: String(item.json.label).length,\n  payload_chars: String(item.json.payload).length,\n  started_at_ms: Number(item.json.started_at_ms)\n} }));"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -40,
        0
      ],
      "id": "bd5ca50a-e9ba-4236-b83a-0fe12c74f8b5",
      "name": "Normalize locally"
    },
    {
      "parameters": {
        "jsCode": "const items = $input.all();\nif (items.length === 0) throw new Error('PREFLIGHT_NO_ITEMS');\nconst startedAtMs = Number(items[0].json.started_at_ms);\nreturn [{ json: {\n  item_count: items.length,\n  amount_sum: items.reduce((sum, item) => sum + Number(item.json.amount), 0),\n  id_sum: items.reduce((sum, item) => sum + Number(item.json.id), 0),\n  unique_buckets: new Set(items.map((item) => item.json.bucket)).size,\n  payload_chars_total: items.reduce((sum, item) => sum + Number(item.json.payload_chars), 0),\n  in_workflow_elapsed_ms: Math.max(0, Date.now() - startedAtMs)\n} }];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        220,
        0
      ],
      "id": "56cf98c8-8407-4f19-b938-98a20bf03f94",
      "name": "Aggregate observations"
    },
    {
      "parameters": {
        "jsCode": "const expected = {\n  item_count: 2500,\n  amount_sum: 126250,\n  id_sum: 3126250,\n  unique_buckets: 20,\n  payload_chars_total: 320000\n};\nfor (const [key, value] of Object.entries(expected)) {\n  if ($json[key] !== value) {\n    throw new Error(`PREFLIGHT_ASSERT_${key.toUpperCase()}_${$json[key]}_NE_${value}`);\n  }\n}\nreturn [{ json: {\n  preflight_pass: true,\n  ...expected,\n  in_workflow_elapsed_ms: $json.in_workflow_elapsed_ms,\n  credentials_required: 0,\n  external_calls: 0,\n  file_writes: 0,\n  scope: 'bounded synthetic transformation only',\n  next_step: 'repeat, observe process memory and swap externally, then test your own representative workflow'\n} }];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        480,
        0
      ],
      "id": "f57021ef-62d0-4e74-a2d6-a6ef880812ef",
      "name": "Assert preflight contract"
    }
  ],
  "connections": {
    "Run preflight manually": {
      "main": [
        [
          {
            "node": "Generate bounded synthetic items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run as a sub-workflow": {
      "main": [
        [
          {
            "node": "Generate bounded synthetic items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate bounded synthetic items": {
      "main": [
        [
          {
            "node": "Normalize locally",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize locally": {
      "main": [
        [
          {
            "node": "Aggregate observations",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate observations": {
      "main": [
        [
          {
            "node": "Assert preflight contract",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "b8424385-85c4-4ea4-9d9c-8ab35324bbb7",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "tags": []
}
