diff --git a/py/mpconfig.h b/py/mpconfig.h
index 78147609ca9e9a6d07a03c43cd848087135fc05e..435140dc72571ecffdc389632ab59c4ef59fb577 100644
--- a/py/mpconfig.h
+++ b/py/mpconfig.h
@@ -33,6 +33,39 @@
 // Any options not explicitly set in mpconfigport.h will get default
 // values below.
 
+/*****************************************************************************/
+/* Memory allocation policy                                                  */
+
+// Initial amount for parse rule stack
+#ifndef MP_ALLOC_PARSE_RULE_INIT
+#define MP_ALLOC_PARSE_RULE_INIT (64)
+#endif
+
+// Increment for parse rule stack
+#ifndef MP_ALLOC_PARSE_RULE_INC
+#define MP_ALLOC_PARSE_RULE_INC (16)
+#endif
+
+// Initial amount for parse result stack
+#ifndef MP_ALLOC_PARSE_RESULT_INIT
+#define MP_ALLOC_PARSE_RESULT_INIT (32)
+#endif
+
+// Increment for parse result stack
+#ifndef MP_ALLOC_PARSE_RESULT_INC
+#define MP_ALLOC_PARSE_RESULT_INC (16)
+#endif
+
+// Initial amount for ids in a scope
+#ifndef MP_ALLOC_SCOPE_ID_INIT
+#define MP_ALLOC_SCOPE_ID_INIT (4)
+#endif
+
+// Increment for ids in a scope
+#ifndef MP_ALLOC_SCOPE_ID_INC
+#define MP_ALLOC_SCOPE_ID_INC (6)
+#endif
+
 /*****************************************************************************/
 /* Micro Python emitters                                                     */
 
diff --git a/py/parse.c b/py/parse.c
index 13b137fb3452dd772c37fc681c10e3f6c1e32663..f512eea3b2d0b36d9e7874790974bcc2dc801d62 100644
--- a/py/parse.c
+++ b/py/parse.c
@@ -134,13 +134,13 @@ STATIC void push_rule(parser_t *parser, int src_line, const rule_t *rule, int ar
         return;
     }
     if (parser->rule_stack_top >= parser->rule_stack_alloc) {
-        rule_stack_t *rs = m_renew_maybe(rule_stack_t, parser->rule_stack, parser->rule_stack_alloc, parser->rule_stack_alloc * 2);
+        rule_stack_t *rs = m_renew_maybe(rule_stack_t, parser->rule_stack, parser->rule_stack_alloc, parser->rule_stack_alloc + MP_ALLOC_PARSE_RULE_INC);
         if (rs == NULL) {
             memory_error(parser);
             return;
         }
         parser->rule_stack = rs;
-        parser->rule_stack_alloc *= 2;
+        parser->rule_stack_alloc += MP_ALLOC_PARSE_RULE_INC;
     }
     rule_stack_t *rs = &parser->rule_stack[parser->rule_stack_top++];
     rs->src_line = src_line;
@@ -263,13 +263,13 @@ STATIC void push_result_node(parser_t *parser, mp_parse_node_t pn) {
         return;
     }
     if (parser->result_stack_top >= parser->result_stack_alloc) {
-        mp_parse_node_t *pn = m_renew_maybe(mp_parse_node_t, parser->result_stack, parser->result_stack_alloc, parser->result_stack_alloc * 2);
+        mp_parse_node_t *pn = m_renew_maybe(mp_parse_node_t, parser->result_stack, parser->result_stack_alloc, parser->result_stack_alloc + MP_ALLOC_PARSE_RESULT_INC);
         if (pn == NULL) {
             memory_error(parser);
             return;
         }
         parser->result_stack = pn;
-        parser->result_stack_alloc *= 2;
+        parser->result_stack_alloc += MP_ALLOC_PARSE_RESULT_INC;
     }
     parser->result_stack[parser->result_stack_top++] = pn;
 }
@@ -350,11 +350,11 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, mp_p
 
     parser->had_memory_error = false;
 
-    parser->rule_stack_alloc = 64;
+    parser->rule_stack_alloc = MP_ALLOC_PARSE_RULE_INIT;
     parser->rule_stack_top = 0;
     parser->rule_stack = m_new(rule_stack_t, parser->rule_stack_alloc);
 
-    parser->result_stack_alloc = 64;
+    parser->result_stack_alloc = MP_ALLOC_PARSE_RESULT_INIT;
     parser->result_stack_top = 0;
     parser->result_stack = m_new(mp_parse_node_t, parser->result_stack_alloc);
 
diff --git a/py/scope.c b/py/scope.c
index 8d3f7bada2428d32d55250d1021baf7bf1e28aa0..ab29af78abb86868a636771f0d8ac31ace46655b 100644
--- a/py/scope.c
+++ b/py/scope.c
@@ -71,7 +71,7 @@ scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, qstr source_file, uint
     }
     scope->raw_code = mp_emit_glue_new_raw_code();
     scope->emit_options = emit_options;
-    scope->id_info_alloc = 8;
+    scope->id_info_alloc = MP_ALLOC_SCOPE_ID_INIT;
     scope->id_info = m_new(id_info_t, scope->id_info_alloc);
 
     return scope;
@@ -92,8 +92,8 @@ id_info_t *scope_find_or_add_id(scope_t *scope, qstr qstr, bool *added) {
 
     // make sure we have enough memory
     if (scope->id_info_len >= scope->id_info_alloc) {
-        scope->id_info = m_renew(id_info_t, scope->id_info, scope->id_info_alloc, scope->id_info_alloc * 2);
-        scope->id_info_alloc *= 2;
+        scope->id_info = m_renew(id_info_t, scope->id_info, scope->id_info_alloc, scope->id_info_alloc + MP_ALLOC_SCOPE_ID_INC);
+        scope->id_info_alloc += MP_ALLOC_SCOPE_ID_INC;
     }
 
     // add new id to end of array of all ids; this seems to match CPython