You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
SK-3133 add SDK Guidelines: Unary vs Bulk Operations to flowvault README
New top-level section (after VaultController -- Unary operations, before
Bulk Insert) covering:
- Unary vs Bulk: when to use each, mirroring the structural comparison
table already in the README with practical decision guidance.
- The N < batchSize trap where bulk resolves to concurrency=1 with none
of the batching benefit.
- Concurrency guidelines: a starting-point sizing formula
(N_cpu x U_cpu x (1 + W/C)) for ..._CONCURRENCY_LIMIT, with guidance
to benchmark and raise incrementally rather than jump to the
formula's theoretical max.
Also renames the existing structural comparison heading from
"Unary vs. bulk" to "Unary vs. bulk Parity" to disambiguate it from
the new guidance section's title.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@@ -629,7 +633,7 @@ Alongside the bulk methods, `VaultController` exposes five **unary** operations.
629
633
630
634
Each method also accepts an optional options object (`InsertOptions`, `DetokenizeOptions`, `GetOptions`, `UpdateOptions`, `DeleteOptions`) — see [Custom Request Headers](#custom-request-headers).
631
635
632
-
## Unary vs. bulk
636
+
## Unary vs. bulk Parity
633
637
634
638
Everything the bulk machinery adds — batching, concurrency, the payload ceiling, the summary, the per-item index — is absent here. What survives is the per-record reporting:
635
639
@@ -655,6 +659,58 @@ The same distinction as [Schema vs. schemaless vaults](#schema-vs-schemaless-vau
655
659
|`delete`| Structured vaults — deletes a table's records. Distinct from `bulkDeleteTokens`, which removes tokens only and leaves the record in place. |
656
660
|`detokenize`| Both — detokenizing only needs the token itself, not a table, so it works regardless of which kind of vault the token came from. |
657
661
662
+
# SDK Guidelines: Unary vs Bulk Operations
663
+
664
+
Both **Unary** and **Bulk** operations accept as many records as you pass. The key difference is **how the SDK makes HTTP calls and manages concurrency**.
665
+
666
+
## Unary
667
+
668
+
- Makes **exactly one HTTP call per SDK invocation**, regardless of the number of records.
669
+
- The application is responsible for any **chunking, batching, and concurrency**.
670
+
- Best suited for:
671
+
- Single-event or low-volume ingestion
672
+
- Interactive or user-facing requests where immediate results are required
673
+
- Applications that already have their own concurrency or job-management mechanism
674
+
675
+
**Use Unary when you want the application to control request execution.**
676
+
677
+
## Bulk
678
+
679
+
- The SDK automatically splits records into `batchSize`-sized chunks.
680
+
- It dispatches up to `concurrencyLimit` batches in parallel.
681
+
- The SDK therefore owns **batching, parallel dispatch, and request coordination**.
682
+
- Best suited for:
683
+
- Large datasets
684
+
- Imports and backfills
685
+
- ETL and data migration workloads
686
+
- Bulk/streaming ingestion where you want the SDK to manage batching and concurrency
687
+
688
+
**Use Bulk when you want the SDK to optimize request execution for high-volume workloads.**
689
+
690
+
A bulk call sent with fewer records than `batchSize` (default 50) still produces exactly one batch — `concurrency` resolves to 1 regardless of `..._CONCURRENCY_LIMIT` — so there's no batching benefit, only the overhead of the bulk machinery on top. Use unary instead for calls at that size.
691
+
692
+
## Concurrency guidelines
693
+
694
+
For Bulk operations, choose `concurrencyLimit` based on the available CPU and the ratio of task wait time to compute time:
695
+
696
+
```
697
+
concurrency ≈ N_cpu × U_cpu × (1 + W/C)
698
+
```
699
+
700
+
Where:
701
+
702
+
-`N_cpu` = number of CPU cores available to the process
703
+
-`U_cpu` = target CPU utilization, between 0 and 1
704
+
-`W` = wait time / API latency per call
705
+
-`C` = compute time per call — approximately **5 ms for the SDK**
706
+
707
+
### Practical guidance
708
+
709
+
-**VUs ≤ 20:** a single CPU core is generally sufficient.
710
+
-**VUs > 20:** consider increasing CPU capacity and tune concurrency accordingly.
711
+
- For higher-throughput workloads, **dual- or quad-core** configurations are a good starting point.
712
+
- Start with the formula as a baseline and **benchmark with your actual API latency and workload** before increasing concurrency further.
713
+
658
714
# Bulk Insert
659
715
660
716
Insert many records — even across different tables — in a single call. Each record is a `BulkInsertRequestRecord` with its own `data` and, optionally, its own `tableName` and `upsert`.
0 commit comments