$opt->{batch_size} and
                $env = { XAPIAN_FLUSH_THRESHOLD => '4294967295' };
 
-       for my $k (qw(sequential_shard)) {
+       for my $k (qw(sequential-shard)) {
                my $git_key = "publicInbox.index".ucfirst($k);
-               $git_key =~ s/_([a-z])/\U$1/g;
+               $git_key =~ s/-([a-z])/\U$1/g;
                defined(my $s = $opt->{$k} // $cfg->{lc($git_key)}) or next;
                defined(my $v = $cfg->git_bool($s))
                                        or die "`$git_key=$s' not boolean\n";
 
 sub index_opt {
        # TODO: drop underscore variants everywhere, they're undocumented
        qw(fsync|sync! jobs|j=i indexlevel|L=s compact
-       max_size|max-size=s sequential_shard|sequential-shard
+       max_size|max-size=s sequential-shard
        batch_size|batch-size=s skip-docdata)
 }
 
        'do not index messages larger than SIZE (default: infinity)' ],
 'batch_size|batch-size=s' => [ 'SIZE',
        'flush changes to OS after given number of bytes (default: 1m)' ],
-'sequential_shard|sequential-shard' =>
+'sequential-shard' =>
        'index Xapian shards sequentially for slow storage',
 'skip-docdata' =>
        'drop compatibility w/ public-inbox <1.6 to save ~1.5% space',
 
 
 sub xapian_only {
        my ($self, $opt, $sync, $art_beg) = @_;
-       my $seq = $opt->{sequential_shard};
+       my $seq = $opt->{'sequential-shard'};
        $art_beg //= 0;
        local $self->{parallel} = 0 if $seq;
        $self->idx_init($opt); # acquire lock
        }
 
        my $pr = $opt->{-progress};
-       my $seq = $opt->{sequential_shard};
+       my $seq = $opt->{'sequential-shard'};
        my $art_beg; # the NNTP article number we start xapian_only at
        my $idxlevel = $self->{ibx}->{indexlevel};
        local $self->{ibx}->{indexlevel} = 'basic' if $seq;
 
                qw(verbose|v+ rethread compact|c+ fsync|sync!
                indexlevel|index-level|L=s max_size|max-size=s
                batch_size|batch-size=s
-               sequential_shard|sequential-shard|seq-shard
+               sequential-shard|seq-shard
                )) or die $help;
 if ($opt->{help}) { print $help; exit 0 };
 my $old_dir = shift(@ARGV) // '';
 
                fsync|sync! xapian_only|xapian-only
                indexlevel|index-level|L=s max_size|max-size=s
                batch_size|batch-size=s
-               sequential_shard|seq-shard|sequential-shard
+               sequential-shard|seq-shard
                no-update-extindex update-extindex|E=s@
                fast-noop|F skip-docdata all help|h))
        or die $help;
                defined(my $v = $cfg->git_bool($s)) or die <<EOL;
 publicInbox.$ibx->{name}.indexSequentialShard not boolean
 EOL
-               $ibx_opt = { %$opt, sequential_shard => $v };
+               $ibx_opt = { %$opt, 'sequential-shard' => $v };
        }
        my $nidx = PublicInbox::Admin::index_inbox($ibx, undef, $ibx_opt);
        last if $ibx_opt->{quit};
        if (my $copt = $opt->{compact_opt}) {
-               local $copt->{jobs} = 0 if $ibx_opt->{sequential_shard};
+               local $copt->{jobs} = 0 if $ibx_opt->{'sequential-shard'};
                PublicInbox::Xapcmd::run($ibx, 'compact', $copt);
        }
        last if $ibx_opt->{quit};
 
 GetOptions($opt, qw(
        fsync|sync! compact|c reshard|R=i
        max_size|max-size=s batch_size|batch-size=s
-       sequential_shard|seq-shard|sequential-shard
+       sequential-shard|seq-shard
        jobs|j=i quiet|q verbose|v
        blocksize|b=s no-full|n fuller|F
        all help|h)) or die $help;
 # know sizes, only doccounts
 $opt->{-idx_env} = $idx_env;
 
-if ($opt->{sequential_shard} && ($opt->{jobs} // 1) > 1) {
+if ($opt->{'sequential-shard'} && ($opt->{jobs} // 1) > 1) {
        warn "W: --jobs=$opt->{jobs} ignored with --sequential-shard\n";
        $opt->{jobs} = 0;
 }