A table's rows are ordered either in rowid-order (or in PK-order for without-rowid tables), there's nothing you can do about that. Modulo page-fragmentation of course, which you get rid of with vacuum. So either you do your inserts in geohash-order, when you don't want to control the rowid, or you alias the rowid with an INTEGER PRIMARY KEY column, which is derived from your geohash **and** is UNIQUE of course... That's not too different from your without-rowid analysis, which is correct to me. If you don't care about controlling the rowid, you can also do a [CTAS][CTAS] to *re-order* your table into another one, and replace (delete+rename) the old one. Because CTAS's doc says: > Rows are assigned contiguously ascending rowid values, starting with 1, > in the order that they are returned by the SELECT statement Thus if the CTAS's right-hand-side SELECT is ordered by GeoHash, so will the table be as well. That's basically equivalent to a _custom vacuum_ for that table, kinda... But in all cases, that geohash ordering (i.e. clustering) won't be maintained against further DMLs, which might be OK if you're *read-mostly*. I guess you could also create an non-unique covering index, with the geohash as the first column, which would act as a kind of _shadow table_, with enough columns in it that most queries don't need to go back to the _main_ table. You gain automatic maintenance of that index, in geohash order, but at the cost of duplicating your table... [CTAS]: https://www.sqlite.org/lang_createtable.html#createtabas