HN user

danielmewes

93 karma
Posts3
Comments53
View on HN

Author here.

We originally developed our evolution-inspired tool to optimize LLM prompts. To our surprise, we found that the same method also worked well for getting better performance out of a base model on ARC-AGI tasks.

We're open-sourcing the evolver tool today. It is built to be adapted to many different optimization problems. (Some coding required) You can read more about it at https://imbue.com/research/2026-02-27-darwinian-evolver/

Happy to answer questions!

Edit: While Horizon assigns versions internally, it looks like they are not currently used for catching concurrent client-side modifications by different users. (I previously wrote that they would cause the "losing" write to fail if it was based on an outdated version of the data, but that doesn't seem to be the case yet.)

I opened an issue against our docs to add information on this, as I'm a bit fuzzy on the detailed behavior myself: https://github.com/rethinkdb/horizon-docs/issues/50

Daniel @ RethinkDB here.

We're constantly improving performance and a lot has happened within the past year. I think that at this point RethinkDB is as good a database for analytics as many of the other general-purpose databases when it comes to features and performance.

From what I can tell, there are still two main limitations that apply in some, but not all scenarios:

* Grouping big results without an associated aggregation requires the full result to fit into RAM. I believe this was the limitation that you ran into a year ago, which lead to RAM exhaustion. This limitation is still there ( https://github.com/rethinkdb/rethinkdb/issues/2719 in our issue tracker). However we're shipping a new command `fold` with the upcoming 2.3 release of RethinkDB, which can be used in the vast majority of cases to perform streaming grouped operations (in conjunction with a matching index). See https://github.com/rethinkdb/rethinkdb/issues/3736 for details.

* Scanning data sets that don't fit into memory on rotational disks is still inefficient. Most SQL databases deploy sophisticated optimizations to structure their disk layout in order to minimize the effects of high seek times. RethinkDB's disk layout it built with a stronger focus on SSDs. This limitation hence doesn't apply if the data is stored on SSDs.

We've heard from a lot of users who want to run RethinkDB on their Windows computer for development purposes.

Production servers could then run on either Linux or Windows.

I'm not too familiar with Microsoft's licensing terms, so I can't really comment on that aspect.

That's not what http://rethinkdb.com/docs/quickstart/ says. It shows a connection that exposes context-bound Builder methods with trigger (insert, changes, run, etc) methods.

I think the confusion stems from the fact that the Quickstart guide assumes that you're running queries in the Data Explorer, a web frontend for prototyping queries. In the Data Explorer, clicking the "Run" button is what triggers the execution of the AST.

If you wrote something like `r.table("tv_shows").insert(...)` in your application code, it wouldn't do anything except for returning an AST object. You can store that object, or call the `run(conn)` method on it to send it over a RethinkDB connection and execute it.

Note that the `r` object in these queries has no state. You can think of it as a namespace that serves as a starting point for building queries.

You might want to check out the new Windows build instructions here: https://github.com/rethinkdb/rethinkdb/blob/atnnn/windows2/W...

We've since simplified the build process, and it can now build most dependencies automatically. The only exception right now are the web UI assets which still need to be downloaded separately or copied from Linux (building these on Windows will come later).

We don't link or compile in any Cygwin code, and use all Windows APIs directly. The build system uses some Cygwin tools though. Incidentally we considered using Cygwin to achieve Windows compatibility at some point, but found that it didn't implement some of the lower-level APIs that RethinkDB uses on Linux.

A new epoch timestamp is generated when you either first create a new table, or when you use the "emergency repair" operation to manually recover from a dead Raft cluster (usually one that has lost a majority of servers).

The wall-clock time comes from the server that processes that query.

Whenever the epoch timestamp changes, replicas will get a fresh set of Raft member IDs, and it's expected that they start with an empty Raft log.

Where exactly the epoch timestamps come from is not really relevant to this bug. With the bug fixed, any given node will only accept multi_table_manager_t actions that have a strictly larger epoch timestamp than what they have right now. That is enough to guarantee that they never go back to a previous configuration, and never rejoin a Raft cluster with the old member ID, but a wiped Raft log.

We only submitted the configuration that passed all scenarios, but tested some of the others internally. You generally don't get guaranteed linearizability of operations under network partitions in any of the faster configurations.

We're still working on the full documentation for the Twisted and asyncio backends. We'll put it up in the next days. You can find the Tornado documentation under the link coffeemug mentioned.

If I understand that scenario correctly, it assumes that there is a node that can successfully send messages to the other nodes in the cluster, but cannot receive any responses.

Since RethinkDB uses TCP connections, this shouldn't usually happen (since the TCP acknowledgements wouldn't get through either). The exception might be a layer 5 router / firewall somewhere in the network that allows the TCP connection to work, but only passes the data stream through in one direction. RethinkDB is partially protected against this case, because we use bidirectional heartbeats on top of the same TCP connection that is used for Raft traffic. The heartbeat usually ensures that the other host is still alive and reachable. In this case, the node that cannot receive any responses from the remaining cluster would get a heartbeat timeout after a couple of seconds, and disconnect from the remaining servers. This is turn should limit further damage and allow the Raft cluster to proceed.

Please let me know if I'm missing something else.

Edit: There might still be some problems with non-transitive connectivity, where one node can talk to only parts of the cluster. We have built in some protection against this, but don't always handle that case well.

We haven't added special logic for handling such cases. I think having servers with particularly unstable connectivity in a RethinkDB cluster is really uncommon though. If you want to run a RethinkDB server on your mobile device that's a different scenario of course...

We have carefully designed the way data is versioned and replicated in RethinkDB 2.1 to result in a correct and consistent system in combination with the Raft-supported configuration management. For example we make sure that both components use consistent quorum definitions and the same membership information at any point.

This allows us to provide different degrees of consistency guarantees for the data, depending on the user's need. Our default is already pretty conservative, but allows uncommitted data to be visible by reads. In the strongest consistency mode, RethinkDB 2.1 provides full linearizability (see http://docs.rethinkdb.com/2.1/docs/consistency/ for details). We have confirmed this both theoretically as well as by testing the overall system using the Jepsen test framework.

That's a great question.

In our current architecture, we perform failover by selecting a new primary among the existing replicas for a given shard. We do not however add new servers to the replica list during a failover condition. Therefore, if you have a table with two replicas per shard and have a one node failure, you would only have a single replica left.

Currently we do not automatically failover in that case. We always require a majority of replicas to be present for any given shard before failing over the primary of that shard.

I believe we could relax this constraint in this specific case, and allow failing over despite only a single replica being left, as long as we still have a majority for the table overall. (I'm going to double-check this with one of our core developers...) Even if we did perform the failover, that would not restore write availability of the table though, since there wouldn't be a majority to acknowledge a write (unless you set write_acks to "single"). It could still be useful to restore availability for up to date read queries. We might add support for auto failover in this scenario in the future.

3 nodes are indeed required to have automatic failover working.

We recommend using 3 (or more) nodes and replicating all tables with a replication factor of 3. That way each node is going to maintain a full copy of the data. In case of a 1 node failure (with or without sharding, as long as the replication factor is set to 3), one of the two remaining servers is going to take over for the primary roles that might have been hosted on the missing server.

If you want to sustain a two node failure without any data loss, you will need 5 servers and also set the replication factor to 5. 5 is the lowest number that guarantees that if two nodes fail, you will still be left with a majority of replicas (i.e. 3 out of 5). A majority like that is required to guarantee data durability and to enable auto failover. If you are ok with losing a few seconds worth of changes and do not require automatic failover, even a 3 node setup can be enough to sustain a two node failure. In that case you will have to perform a manual "emergency_repair" to recover availability (see http://docs.rethinkdb.com/2.1/api/javascript/reconfigure/ for details), but most of the data should still be there.

In addition you can shard the table into 3 shards for additional performance gains. This is for the most part unrelated to availability and data safety.

General query performance should be the same, if not better in this release (the improvements are not due to Raft, but due to other changes). We use Raft only to determine a consistent configuration. The queries themselves are executed in the same efficient way as before.

Note that in the beta, reconfiguring tables over servers on rotational disks can be slow https://github.com/rethinkdb/rethinkdb/issues/4279 . If you store large documents, you might also see some increases in memory usage during backfills https://github.com/rethinkdb/rethinkdb/issues/4474 . We're going to address both of these issues before the final release.

(Daniel at RethinkDB here) Thanks for the nice words. We're going to add changefeeds that can survive short client disconnects in 2.2, and add further reliability features for changefeeds in the following versions.

Note that (according to the linked commits), RethinkDB is using what we call "hard" durability in this comparison. This is our default to ensure maximum data safety.

Hard durability means that every individual write will wait for the data to be written to disk before the next one is run (in this benchmark, since it only does one at a time).

I don't think any of the other databases in this test is using a similarly strict requirement, are they?

You'd have to run with the currently commented line "rethinkdb.db('talks').table_create('talks', durability='soft').run(conn)" to get more comparable results.

(Edit for clarification: `durability='soft'` is comparable to the `safe` flag in many of the MongoDB drivers. It means that the server will acknowledge each write when it has been applied, but not wait for disk writes to complete.)

Daniel @ RethinkDB here. We're going to ship an official Java driver very soon. We decided to focus on a small number of core drivers first while the protocol and query language were still undergoing rapid extension. Now that the protocol is stable, we're going to expand our official driver support step by step. The Java one will be first.

You can follow the progress on https://github.com/rethinkdb/rethinkdb/issues/3930

It's not currently on our road map.

Even though there are some well-researched algorithms for it, actually implementing transactions in a distributed system is pretty hard. It also comes at significant performance costs, which would interfere with our goal of easy and efficient scalability.

As a second data point: I tried

    table.groupBy(function (x) { ... }).count()
where the function maps the documents into one out of 32 groups (so that's less than your 94, but shouldn't make a giant difference... I just had this database around). Did that on both 1 million and a 25 million document table, and memory usage looked fine and very stable. This was on RethinkDB 2.0, and I might retry that on 1.16 later to see if I can reproduce it there.

Do you remember if you had set an explicit cache size back when you were testing RethinkDB?