diff --git a/common/speculative.cpp b/common/speculative.cpp
index ee94d7c..d736415 100644
--- a/common/speculative.cpp
+++ b/common/speculative.cpp
@@ -2274,6 +2274,9 @@ common_speculative_init_result::common_speculative_init_result(
 
     if (spec_mtp) {
         cparams.ctx_type = LLAMA_CONTEXT_TYPE_MTP;
+        // use the same (possibly fit-reduced) context size as the target
+        // avoids MTP draft reserving flash attention workspace for full n_ctx
+        cparams.n_ctx = llama_n_ctx(ctx_tgt);
     }
 
     // note: for small models maybe we can set this to the maximum possible draft from all speculative types
diff --git a/tools/server/server-context.cpp b/tools/server/server-context.cpp
index 744593c..47c381c 100644
--- a/tools/server/server-context.cpp
+++ b/tools/server/server-context.cpp
@@ -1091,6 +1091,19 @@ private:
                 auto cparams_dft = common_context_params_to_llama(params_dft);
                 if (spec_mtp) {
                     cparams_dft.ctx_type = LLAMA_CONTEXT_TYPE_MTP;
+                    // MTP draft uses the target's (possibly fit-reduced) n_ctx at runtime.
+                    // Estimate with the same n_ctx to avoid over-reserving fit_params_target.
+                    {
+                        auto mparams_tgt = common_model_params_to_llama(params_base);
+                        auto cparams_tgt = common_context_params_to_llama(params_base);
+                        common_fit_params(params_dft.model.path.c_str(), &mparams_tgt, &cparams_tgt,
+                            params_base.tensor_split,
+                            params_base.tensor_buft_overrides.data(),
+                            params_base.fit_params_target.data(),
+                            params_base.fit_params_min_ctx,
+                            GGML_LOG_LEVEL_ERROR);
+                        cparams_dft.n_ctx = cparams_tgt.n_ctx;
+                    }
                 }
                 cparams_dft.n_rs_seq = 0;
 
@@ -1115,7 +1128,11 @@ private:
                     }
 
                     for (size_t j = 0; j < devs.size(); ++j) {
-                        const size_t bytes = (measure_model_bytes ? dmd[j].model : 0) + dmd[j].context + dmd[j].compute;
+                        // MTP draft shares the target's compute buffer, so only count context memory.
+                        // Draft models (separate model file) need their own compute buffer.
+                        const size_t bytes = (measure_model_bytes ? dmd[j].model : 0)
+                            + dmd[j].context
+                            + (spec_mtp ? 0 : dmd[j].compute);
                         total += bytes;
                         for (size_t i = 0; i < tgt_devices.size(); i++) {
                             if (tgt_devices[i] == devs[j]) {
