diff --git a/btpd/cli_if.c b/btpd/cli_if.c
index c28382c..8be8320 100644
--- a/btpd/cli_if.c
+++ b/btpd/cli_if.c
@@ -1,4 +1,5 @@
 #include "btpd.h"
+#include "utils.h"
 
 #include <sys/un.h>
 #include <iobuf.h>
@@ -440,8 +441,6 @@ static struct {
     { "tget",   4, cmd_tget }
 };
 
-static int ncmds = sizeof(cmd_table) / sizeof(cmd_table[0]);
-
 static int
 cmd_dispatch(struct cli *cli, const char *buf)
 {
@@ -451,7 +450,7 @@ cmd_dispatch(struct cli *cli, const char *buf)
 
     cmd = benc_mem(benc_first(buf), &cmdlen, &args);
 
-    for (int i = 0; i < ncmds; i++) {
+    for (int i = 0; i < ARRAY_COUNT(cmd_table); i++) {
         if ((cmdlen == cmd_table[i].nlen &&
                 strncmp(cmd_table[i].name, cmd, cmdlen) == 0)) {
             return cmd_table[i].fun(cli, benc_nelems(buf) - 1, args);
diff --git a/cli/btcli.c b/cli/btcli.c
index 8d1aada..61eb535 100644
--- a/cli/btcli.c
+++ b/cli/btcli.c
@@ -1,6 +1,7 @@
 #include <stdarg.h>
 
 #include "btcli.h"
+#include "utils.h"
 
 const char *btpd_dir;
 struct ipc *ipc;
@@ -120,8 +121,6 @@ static struct {
     { "stat", cmd_stat, usage_stat }
 };
 
-int ncmds = sizeof(cmd_table) / sizeof(cmd_table[0]);
-
 static void
 usage(void)
 {
@@ -191,7 +190,7 @@ main(int argc, char **argv)
 
     optind = 0;
     int found = 0;
-    for (int i = 0; !found && i < ncmds; i++) {
+    for (int i = 0; !found && i < ARRAY_COUNT(cmd_table); i++) {
         if (strcmp(argv[0], cmd_table[i].name) == 0) {
             found = 1;
             if (help)
diff --git a/cli/list.c b/cli/list.c
index ed346d2..f8659f3 100644
--- a/cli/list.c
+++ b/cli/list.c
@@ -1,4 +1,5 @@
 #include "btcli.h"
+#include "utils.h"
 
 void
 usage_list(void)
@@ -170,7 +171,7 @@ cmd_list(int argc, char **argv)
            IPC_TVAL_PCCOUNT, IPC_TVAL_PCSEEN, IPC_TVAL_PCGOT,   IPC_TVAL_SESSUP,
            IPC_TVAL_SESSDWN, IPC_TVAL_RATEUP, IPC_TVAL_RATEDWN, IPC_TVAL_IHASH,
            IPC_TVAL_DIR };
-    size_t nkeys = sizeof(keys) / sizeof(keys[0]);
+    size_t nkeys = ARRAY_COUNT(keys);
     struct items itms;
     while ((ch = getopt_long(argc, argv, "aif:", list_opts, NULL)) != -1) {
         switch (ch) {
diff --git a/cli/stat.c b/cli/stat.c
index b4ad898..bb7a6a4 100644
--- a/cli/stat.c
+++ b/cli/stat.c
@@ -1,4 +1,5 @@
 #include "btcli.h"
+#include "utils.h"
 
 void
 usage_stat(void)
@@ -56,7 +57,7 @@ static enum ipc_tval stkeys[] = {
     IPC_TVAL_CSIZE
 };
 
-static size_t nstkeys = sizeof(stkeys) / sizeof(stkeys[0]);
+#define NSTKEYS ARRAY_COUNT(stkeys)
 
 static void
 print_stat(struct btstat *st)
@@ -129,10 +130,10 @@ again:
     bzero(&cba.tot, sizeof(cba.tot));
     cba.tot.state = IPC_TSTATE_INACTIVE;
     if (tps == NULL)
-        err = btpd_tget_wc(ipc, IPC_TWC_ACTIVE, stkeys, nstkeys,
+        err = btpd_tget_wc(ipc, IPC_TWC_ACTIVE, stkeys, NSTKEYS,
             stat_cb, &cba);
     else
-        err = btpd_tget(ipc, tps, ntps, stkeys, nstkeys, stat_cb, &cba);
+        err = btpd_tget(ipc, tps, ntps, stkeys, NSTKEYS, stat_cb, &cba);
     if (err != IPC_OK)
         diemsg("command failed (%s).\n", ipc_strerror(err));
     if (names)
diff --git a/misc/utils.h b/misc/utils.h
new file mode 100644
index 0000000..d996779
--- /dev/null
+++ b/misc/utils.h
@@ -0,0 +1,7 @@
+#ifndef BTPD_UTILS_H
+#define BTPD_UTILS_H
+
+/* get the number of elements in a static table */
+#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
+
+#endif