diff --git a/src/adb.c b/src/adb.c
index e0cc3bcf7522b7c88c373e89a940ccd282efa949..16b2c8b66ca5873656085e25e5ce8733ebd720e9 100644
--- a/src/adb.c
+++ b/src/adb.c
@@ -819,6 +819,12 @@ struct adb_obj *adb_wo_init_val(struct adb_obj *o, adb_val_t *p, const struct ad
 	return adb_wo_init(o, p, schema, parent->db);
 }
 
+void adb_wo_free(struct adb_obj *o)
+{
+	if (o->dynamic) free(o->obj);
+	o->obj = 0;
+}
+
 void adb_wo_reset(struct adb_obj *o)
 {
 	uint32_t max = o->obj[ADBI_NUM_ENTRIES];
@@ -930,9 +936,20 @@ adb_val_t adb_wo_arr(struct adb_obj *o, unsigned i, struct adb_obj *no)
 adb_val_t adb_wa_append(struct adb_obj *o, adb_val_t v)
 {
 	assert(o->schema->kind == ADB_KIND_ARRAY);
-	if (o->num >= o->obj[ADBI_NUM_ENTRIES]) return adb_w_error(o->db, E2BIG);
 	if (ADB_IS_ERROR(v)) return adb_w_error(o->db, ADB_VAL_VALUE(v));
-	if (v != ADB_VAL_NULL) o->obj[o->num++] = v;
+	if (v == ADB_VAL_NULL) return v;
+
+	if (o->num >= o->obj[ADBI_NUM_ENTRIES]) {
+		int num = o->obj[ADBI_NUM_ENTRIES];
+		adb_val_t *obj = reallocarray(o->dynamic ? o->obj : NULL, num * 2, sizeof(adb_val_t));
+		if (!obj) return adb_w_error(o->db, ENOMEM);
+		if (!o->dynamic) memcpy(obj, o->obj, sizeof(adb_val_t) * num);
+		memset(&obj[num], 0, sizeof(adb_val_t) * num);
+		o->obj = obj;
+		o->obj[ADBI_NUM_ENTRIES] = num * 2;
+		o->dynamic = 1;
+	}
+	o->obj[o->num++] = v;
 	return v;
 }
 
diff --git a/src/adb.h b/src/adb.h
index 3372c07f273336ecfcfcd4e566a0289ad922c252..7c1869c6ac780bf67b7ced99fee9c6669b278db7 100644
--- a/src/adb.h
+++ b/src/adb.h
@@ -161,8 +161,9 @@ struct adb {
 struct adb_obj {
 	struct adb *db;
 	const struct adb_object_schema *schema;
-	uint32_t num;
 	adb_val_t *obj;
+	uint32_t num;
+	uint32_t dynamic : 1;
 };
 
 /* Container read interface */
@@ -214,6 +215,7 @@ adb_val_t adb_w_fromstring(struct adb *, const uint8_t *kind, apk_blob_t);
 
 struct adb_obj *adb_wo_init(struct adb_obj *, adb_val_t *, const struct adb_object_schema *, struct adb *);
 struct adb_obj *adb_wo_init_val(struct adb_obj *, adb_val_t *, const struct adb_obj *, unsigned i);
+void adb_wo_free(struct adb_obj *);
 void adb_wo_reset(struct adb_obj *);
 void adb_wo_resetdb(struct adb_obj *);
 adb_val_t adb_w_obj(struct adb_obj *);
diff --git a/src/apk_adb.c b/src/apk_adb.c
index 0b3f36c0aa5a78b10a5659cff04d46169d52a279..7d8b1fb2ddff0f769289e4bd55f4c0c2689dace6 100644
--- a/src/apk_adb.c
+++ b/src/apk_adb.c
@@ -110,7 +110,7 @@ static struct adb_scalar_schema scalar_mstring = {
 
 const struct adb_object_schema schema_string_array = {
 	.kind = ADB_KIND_ARRAY,
-	.num_fields = APK_MAX_PKG_TRIGGERS,
+	.num_fields = 32,
 	.fields = ADB_ARRAY_ITEM(scalar_string),
 };
 
@@ -373,7 +373,7 @@ static int dependencies_fromstring(struct adb_obj *obj, apk_blob_t b)
 const struct adb_object_schema schema_dependency_array = {
 	.kind = ADB_KIND_ARRAY,
 	.fromstring = dependencies_fromstring,
-	.num_fields = APK_MAX_PKG_DEPENDENCIES,
+	.num_fields = 32,
 	.pre_commit = adb_wa_sort_unique,
 	.fields = ADB_ARRAY_ITEM(schema_dependency),
 };
@@ -408,7 +408,7 @@ const struct adb_object_schema schema_pkginfo = {
 
 const struct adb_object_schema schema_pkginfo_array = {
 	.kind = ADB_KIND_ARRAY,
-	.num_fields = APK_MAX_INDEX_PACKAGES,
+	.num_fields = 128,
 	.pre_commit = adb_wa_sort,
 	.fields = ADB_ARRAY_ITEM(schema_pkginfo),
 };
@@ -450,7 +450,7 @@ const struct adb_object_schema schema_file = {
 const struct adb_object_schema schema_file_array = {
 	.kind = ADB_KIND_ARRAY,
 	.pre_commit = adb_wa_sort,
-	.num_fields = APK_MAX_MANIFEST_FILES,
+	.num_fields = 128,
 	.fields = ADB_ARRAY_ITEM(schema_file),
 };
 
@@ -468,7 +468,7 @@ const struct adb_object_schema schema_dir = {
 const struct adb_object_schema schema_dir_array = {
 	.kind = ADB_KIND_ARRAY,
 	.pre_commit = adb_wa_sort,
-	.num_fields = APK_MAX_MANIFEST_PATHS,
+	.num_fields = 128,
 	.fields = ADB_ARRAY_ITEM(schema_dir),
 };
 
@@ -508,7 +508,7 @@ const struct adb_adb_schema schema_package_adb = {
 const struct adb_object_schema schema_package_adb_array = {
 	.kind = ADB_KIND_ARRAY,
 	.pre_commit = adb_wa_sort,
-	.num_fields = APK_MAX_INDEX_PACKAGES,
+	.num_fields = 128,
 	.fields = ADB_ARRAY_ITEM(schema_package_adb),
 };
 
diff --git a/src/apk_adb.h b/src/apk_adb.h
index 45c06f1fb957077668ec612ede873a35bc8e8da7..0bc46e92e48cb4b702f22bbf44988d16f7687717 100644
--- a/src/apk_adb.h
+++ b/src/apk_adb.h
@@ -89,13 +89,6 @@ struct adb_data_package {
 #define ADBI_IDB_MAX		0x02
 
 /* */
-#define APK_MAX_PKG_DEPENDENCIES	512
-#define APK_MAX_PKG_REPLACES		32
-#define APK_MAX_PKG_TRIGGERS		32
-#define APK_MAX_INDEX_PACKAGES		20000
-#define APK_MAX_MANIFEST_FILES		12000
-#define APK_MAX_MANIFEST_PATHS		6000
-
 extern const struct adb_object_schema
 	schema_dependency, schema_dependency_array,
 	schema_pkginfo, schema_pkginfo_array,
diff --git a/src/app_convdb.c b/src/app_convdb.c
index 5e60115ef940e5f21ffebbcca7abf881439f8092..f27c03d5ac24bd8816c3a94d1e3636b811544aec 100644
--- a/src/app_convdb.c
+++ b/src/app_convdb.c
@@ -190,6 +190,9 @@ static int convert_idb(struct conv_ctx *ctx, struct apk_istream *is)
 			break;
 		}
 	}
+	adb_wo_free(&triggers);
+	adb_wo_free(&files);
+	adb_wo_free(&paths);
 	return apk_istream_close(is);
 }
 
diff --git a/src/app_mkndx.c b/src/app_mkndx.c
index 33138046dd399a1d506fc1a015eb2756370054de..d7f1d26d07e0872f8ce2c169968348337bd4098a 100644
--- a/src/app_mkndx.c
+++ b/src/app_mkndx.c
@@ -219,7 +219,7 @@ static int mkndx_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *a
 			ADB_SCHEMA_INDEX, trust);
 		if (r) {
 			apk_err(out, "%s: %s", ctx->index, apk_error_str(r));
-			return r;
+			goto done;
 		}
 		adb_ro_obj(adb_r_rootobj(&odb, &oroot, &schema_index), ADBI_NDX_PACKAGES, &opkgs);
 	}
@@ -286,7 +286,8 @@ static int mkndx_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *a
 	}
 	if (errors) {
 		apk_err(out, "%d errors, not creating index", errors);
-		return -1;
+		r = -1;
+		goto done;
 	}
 
 	numpkgs = adb_ra_num(&ctx->pkgs);
@@ -298,14 +299,15 @@ static int mkndx_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *a
 		apk_ostream_to_file(AT_FDCWD, ctx->output, 0644),
 		&ctx->db, trust);
 
-	adb_free(&ctx->db);
-	adb_free(&odb);
-
 	if (r == 0)
 		apk_msg(out, "Index has %d packages (of which %d are new)", numpkgs, newpkgs);
 	else
 		apk_err(out, "Index creation failed: %s", apk_error_str(r));
 
+done:
+	adb_wo_free(&ctx->pkgs);
+	adb_free(&ctx->db);
+	adb_free(&odb);
 
 #if 0
 	apk_hash_foreach(&db->available.names, warn_if_no_providers, &counts);
diff --git a/src/app_mkpkg.c b/src/app_mkpkg.c
index 74c8db832857dbc4f9aeeba2a011aa5674aba161..552ef571c28abd8cf2ea70b284d99f9a50c753b4 100644
--- a/src/app_mkpkg.c
+++ b/src/app_mkpkg.c
@@ -155,12 +155,14 @@ static int mkpkg_process_directory(struct mkpkg_ctx *ctx, int dirfd, struct apk_
 	if (r) {
 		apk_err(out, "failed to process directory '%s': %d",
 			apk_pathbuilder_cstr(&ctx->pb), r);
-		return r;
+		goto done;
 	}
 
 	adb_wo_obj(&fio, ADBI_DI_FILES, &files);
 	adb_wa_append_obj(&ctx->paths, &fio);
-	return 0;
+done:
+	adb_wo_free(&files);
+	return r;
 }
 
 static int mkpkg_process_dirent(void *pctx, int dirfd, const char *entry)
@@ -343,6 +345,7 @@ static int mkpkg_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *a
 		for (i = 0; i < ctx->triggers->num; i++)
 			adb_wa_append_fromstring(&triggers, APK_BLOB_STR(ctx->triggers->item[i]));
 		adb_wo_obj(&pkg, ADBI_PKG_TRIGGERS, &triggers);
+		adb_wo_free(&triggers);
 	}
 	adb_w_rootobj(&pkg);
 
@@ -401,6 +404,7 @@ static int mkpkg_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *a
 	r = apk_ostream_close(os);
 
 err:
+	adb_wo_free(&ctx->paths);
 	adb_free(&ctx->db);
 	if (r) apk_err(out, "failed to create package: %s: %s", ctx->output, apk_error_str(r));
 	return r;