Skip to content

Native build: commit every 1000 rows by default in insert_many, graph_batch and create_vertices - #75

Merged
tae898 merged 1 commit into
native-two-distfrom
native-ingest-commit-defaults
Oct 25, 2026
Merged

tae898 merged 1 commit into
native-two-distfrom
native-ingest-commit-defaults

Conversation

@tae898

@tae898 tae898 commented Oct 25, 2026

Copy link
Copy Markdown
Collaborator

The native build (the arcadedb package) now commits every 1000 rows by default in insert_many and graph_batch, and create_vertices sends and commits 1000 rows per call into the image. The JVM build (arcadedb-jvm) keeps its defaults: insert_many 10,000, graph_batch unset (one commit per flush), create_vertices 100,000 rows per crossing. They are not measured on the JVM yet. Python only: no Java, no rebuild.

Where each default lives

  • insert_many: DEFAULT_INSERT_MANY_COMMIT_EVERY = 1000 in src/arcadedb/_native/database.py, the default of Database.insert_many(commit_every=...). The JVM default stays commit_every: int = 10_000 in src/arcadedb/core.py.
  • graph_batch: NativeGraphBatch.DEFAULT_COMMIT_EVERY = 1000 in src/arcadedb/_native/extras.py. NativeGraphBatch.create fills it in when commit_every is None (an explicit value, 0 included, goes through unchanged). The JVM graph_batch still leaves it unset.
  • create_vertices: the chunk of a native call is now the batch's commit_every (NativeGraphBatch._vertex_chunk), so 1000 by default, graph_batch(commit_every=N) gives N, and commit_every=0 falls back to _BULK_CHUNK (10,000). There is no per-call chunk argument, so the batch's commit_every is the explicit knob. The JVM GraphBatch._BULK_CHUNK stays 100,000.
  • new_edges is not part of the measured change: its crossing chunk stays NativeGraphBatch._BULK_CHUNK = 10_000.

One correction to the pre-registration: it describes the old create_vertices default as two transactions of 100,000 rows. The 100,000 is the JVM base class value. The native class has overridden it with 10,000 since the native port (NativeGraphBatch._BULK_CHUNK), so the native default moves from 10,000 to 1000, not from 100,000.

What changes for users

commit_every is the number of rows in one transaction. Rows that are already committed stay committed if a later chunk fails, and only the transaction that was open is rolled back. With 1000 instead of 10,000, a failed native load keeps its rows up to a commit that is at most 1000 rows behind the failure. Code that relied on a failed insert_many leaving nothing for loads under 10,000 rows must now pass commit_every=0 (one transaction) or open its own transaction (insert_many commits nothing inside the caller's transaction). graph_batch(commit_every=0) gives the old one commit per flush. Passing commit_every=None explicitly is the same as not passing it.

Evidence

A pre-registered laptop A/B on the columnar native wheel: 1,000,000 mixed documents through insert_many, and 200,000 vertices with 500,000 edges through GraphBatch (parallel_flush, one client thread). ab.py --noise, ABBA order, 12 clean pairs for each figure. The A/A controls were clean (docs [0.994, 1.008], graph [0.990, 1.003]). Intervals are 95 % intervals of the median per-round ratio, new default over old default.

Load Wall Young GC copied volume Peak RSS
insert_many, commit_every=1000 [0.822, 0.831] 0.55x 0.955x
insert_many, commit_every=5000 (also passed) [0.903, 0.914] 0.74x 0.971x
GraphBatch, commit_every=1000 with 1000-row create_vertices calls [0.853, 0.864] 0.63x 0.718x

The rule picks the lower median wall ratio when both document sizes pass, so insert_many gets 1000. The runs used an isolate heap of 80 % of RAM. The default is now 50 % (#74), and smaller commits lower the heap a load needs.

Docs

New page how-to/bulk-loads.adoc (in the nav) with the defaults of both packages side by side, the A/B figures, what changes for a failed load, and how to override. The docstrings of insert_many, graph_batch, GraphBatch.create_vertices (JVM build, src/arcadedb/core.py, src/arcadedb/graph_batch.py) and the native insert_many and graph_batch say which default applies where.

Tests

  • tests/test_ingest_defaults.py (both backends, parses the source, starts neither the JVM nor the native library): the JVM defaults are unchanged (10,000; None; 100,000) and the native constants are 1000 with the edge chunk at 10,000.
  • tests/test_native_ingest_defaults.py (native only, listed in conftest.py for the other backend): a duplicate key in the third 1000 rows leaves 2000 rows with the default, 1500 with commit_every=1500, and 0 with 10,000 or 0. graph_batch sends commit_every=1000 to the image by default, an explicit 250 and 0 are sent unchanged, and create_vertices crosses in 1000, 250 and 2500 rows respectively (rows and count forms).
  • tests/test_native_columnar_insert.py counts crossings of one 2,500-row chunk, so an autouse fixture there runs insert_many with its old commit_every of 10,000 (the file is about the columnar entry points, not the default).

Run with ARCADEDB_BACKEND=native on the newest native image, native-lib/columnar-port/libarcadedb.so in the laptop build dir, built 2026-10-25 22:01 (sha256 08a07e401c9b2c7ba16d8595db2e9d3efd2712bf46417d2f0de0590bed9ee47e), foreground, Python 3.13: test_ingest_defaults, test_native_ingest_defaults, test_bulk_insert, test_graph_batch, test_native_columnar_insert, test_dataframe_ingest and test_core: 227 passed, 4 skipped in 9.06s. bandit 1.9.4 (low severity, low confidence) is clean, scripts/check_no_embedded_name.py is ok, isort (profile black) and black are applied. The JVM build was not run.

🤖 Generated with Claude Code

…_batch and create_vertices

A pre-registered laptop A/B on the columnar native wheel (1M documents through insert_many, 200k vertices and 500k edges through GraphBatch) found 1000-row transactions faster (wall 0.822-0.831 and 0.853-0.864 of the old default) and lighter on the young GC. The native defaults become insert_many commit_every 1000 (was 10,000), graph_batch commit_every 1000 (was unset) and a create_vertices chunk equal to the batch's commit_every (was 10,000). An explicit value wins. The JVM defaults are unchanged and pinned by a source-level test.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@tae898
tae898 merged commit a2dfd0c into native-two-dist Oct 25, 2026
27 checks passed
@tae898
tae898 deleted the native-ingest-commit-defaults branch October 25, 2026 16:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant