Skip to content

Are the stock index-type defaults still right, particularly EINDEX_TYPE? #102

Description

@ChristopherA

Following on from #100, where you supplied the wide-index recipe: we
adopted it, documented it, and in the process measured which of the
compiled ceilings actually binds our workload. The answer was not the one
we expected, and it points at a different type than #100 is about. This is
a question about the defaults rather than a request to change them.

What we measured

We build an application platform on DGD (eOSContinuum/eOS-kernellib, a
cloud-server derivative). Driving its composite example through an
authenticated write path -- bearer-token validation, a persistent daemon
mutation, and a synchronous observer per request -- built from this
repository's source at 25dad1dd with no local modifications, on macOS
arm64:

phase objects in use users
platform + application deployed 319 / 10000 1 (console)
+ 20 authenticated principals 339 1
+ 100 audited record writes 341 1
+ 250 connections held simultaneously 841 251 / 255

At 250 concurrent connections -- 98% of the connection cap -- the object
table holds 841, which is 1.3% of the 65535 UINDEX_MAX permits. Object
cost stayed flat at about two per connection from 8 connections to 250.
So this workload exhausts connections while the object table is
essentially empty; reaching the object ceiling by that route would take
roughly 32,000 concurrent connections, which EINDEX_MAX forbids many
times over.

Scope, so the numbers are not read for more than they are: one machine,
one workload shape, one run per phase. The near-zero object cost per
stored record holds because this example keeps records in a daemon's
dataspace -- an application that clones one object per record pays one
each and would press the object table far harder.

The question

Is EINDEX_TYPE = unsigned char still the right default for a driver
that people put on the network?

What makes us ask rather than just rebuild: raising users past 255 is a
rebuild rather than a config edit, since the parser caps the field at
EINDEX_MAX. A driver rebuilt with unsigned short accepts
users = 1000 and still restores state written by a stock build, so from
here the compatibility cost of a wider default looks low. That suggests
either that the one-byte width encodes a tradeoff we should understand --
per-slot memory, or something in the connection tables we have not looked
at -- or that it is mostly historical. We would rather design around the
judgment than guess at it.

A second data point, pointing at different fields

The largest production application we know of on this lineage is SkotOS.
Its shipped skotos.dgd configures objects = 262144 and
swap_size = 1048576, both above what a stock build's range table admits
(config.cpp caps objects at UINDEX_MAX, and swap_size at
SW_UNUSED, which is SECTOR_MAX). That configuration cannot be parsed
by a stock driver at all.

Worth stating against our own argument: it sets users = 100, well under
the cap. So SkotOS is evidence about the object and sector defaults, not
about the connection one.

Two independent lines, then, from different eras and different workload
shapes, each pointing at a different default: a production config that
needs objects and swap sectors well past the stock ceilings, and a
connection-driven workload that runs out of user slots with the object
table almost untouched.

We are not asking you to change anything -- you have far more context on
what these widths cost than we do. Mostly we want to know whether the
defaults still encode a judgment worth designing around, and if so, what
it is.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionQuestion or suggestion.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions