
x86 アーキテクチャに対応した Lambda MicroVMs を試してみた
はじめに
2026年11月11日に、Lambda MicroVMs で x86 アーキテクチャのサポートが発表されました。
2026年6月の GA 時、サポートアーキテクチャは Arm(AWS Graviton)のみでした。今回のアップデートで、Arm と x86 のどちらかを選べるようになりました。
この記事では、東京リージョンで x86 の Lambda MicroVMs を試した結果を紹介します。
x86 の指定
対応バージョンの照会
x86 は、マネージドベースイメージのバージョン 3 以降でサポートされています。list-managed-microvm-image-versions で、バージョンごとの supportedCpuConfigurations を確認できます。
aws lambda-microvms list-managed-microvm-image-versions --image-identifier arn:aws:lambda:ap-northeast-1:aws:microvm-image:al2023-1 --region ap-northeast-1
| バージョン | 作成日(JST) | supportedCpuConfigurations |
|---|---|---|
| 3 | 2026-10-24 | ARM_64, X86_64 |
| 2 | 2026-09-30 | ARM_64 |
| 1 | 2026-07-17 | ARM_64 |
| 0 | 2026-06-18 | ARM_64 |
イメージの作成と起動
マルチアーキテクチャの node:24-alpine をベースにした Dockerfile を使いました。
FROM node:24-alpine
WORKDIR /app
COPY app.js .
EXPOSE 8080
CMD ["node", "app.js"]
create-microvm-image に --cpu-configurations architecture=X86_64 を付けて、x86 のイメージを作りました。AWS CLI のバージョンは 2.40.2 です。
aws lambda-microvms create-microvm-image --name devio-x86-test-x86 --code-artifact uri=s3://amzn-s3-demo-bucket/app.zip --base-image-arn arn:aws:lambda:ap-northeast-1:aws:microvm-image:al2023-1 --build-role-arn arn:aws:iam::123456789012:role/MicroVMBuildRole --cpu-configurations architecture=X86_64
応答に含まれる cpuConfigurations は X86_64 でした。ベースイメージのバージョンを指定しなかったため、baseImageVersion は 3.1 になりました。
"cpuConfigurations": [
{
"architecture": "X86_64"
}
],
このイメージから起動した MicroVM の /arch を呼んだ結果です。EX と TOKEN_x86 は、MicroVM のエンドポイントと認証トークンです。
$ curl -sS -m 30 "https://$EX/arch" -H "X-aws-proxy-auth: $TOKEN_x86"
{"uname_m":"x86_64","process_arch":"x64"}
参考として、--cpu-configurations を付けずに同じ Dockerfile から作ると、Arm のイメージになります。
aws lambda-microvms create-microvm-image --name devio-x86-test-default --code-artifact uri=s3://amzn-s3-demo-bucket/app.zip --base-image-arn arn:aws:lambda:ap-northeast-1:aws:microvm-image:al2023-1 --build-role-arn arn:aws:iam::123456789012:role/MicroVMBuildRole
応答の cpuConfigurations は ARM_64 で、baseImageVersion は x86 と同じ 3.1 でした。
"cpuConfigurations": [
{
"architecture": "ARM_64"
}
],
この Arm のイメージから起動した MicroVM の /arch を呼んだ結果です。EA と TOKEN_default は、その MicroVM のエンドポイントと認証トークンです。
$ curl -sS -m 30 "https://$EA/arch" -H "X-aws-proxy-auth: $TOKEN_default"
{"uname_m":"aarch64","process_arch":"arm64"}
検証に使ったアプリの全文です。
app.js
// 検証用: アーキテクチャと実行環境の CPU・メモリを返す HTTP サーバー(ポート 8080)。
// 読むのは固定のファイルと固定の API だけ。リクエストの内容はパスの分岐にしか使わない。
// 環境変数と /proc/self/environ は読まない。ホスト名は返さない。
const http = require('http');
const os = require('os');
const fs = require('fs');
const { execFileSync } = require('child_process');
const read = (p) => {
try { return fs.readFileSync(p, 'utf8'); } catch (e) { return `ERROR: ${e.code}`; }
};
// /proc/cpuinfo は先頭 1 コアのブロックと、コア数だけ返す。
const CPU_KEYS_X86 = ['vendor_id', 'cpu family', 'model', 'model name', 'stepping', 'microcode', 'cpu MHz', 'cache size', 'flags'];
const CPU_KEYS_ARM = ['BogoMIPS', 'Features', 'CPU implementer', 'CPU architecture', 'CPU variant', 'CPU part', 'CPU revision'];
const cpuinfo = () => {
const text = read('/proc/cpuinfo');
const blocks = text.split(/\n\s*\n/).filter((b) => b.trim());
const first = {};
for (const line of (blocks[0] || '').split('\n')) {
const i = line.indexOf(':');
if (i < 0) continue;
const k = line.slice(0, i).trim();
const v = line.slice(i + 1).trim();
if (CPU_KEYS_X86.includes(k) || CPU_KEYS_ARM.includes(k)) first[k] = v;
}
const flags = (first.flags || '').split(/\s+/).filter(Boolean);
const feats = (first.Features || '').split(/\s+/).filter(Boolean);
return {
processorBlocks: blocks.length,
first,
x86FlagCount: flags.length,
x86Flags: flags.filter((f) => /^(avx|avx2|avx512.*|sse4_2|amx.*|vnni|avx_vnni|bmi2|sha_ni|vaes|vpclmulqdq|gfni|rdrand|rdseed|adx|fma|erms|fsrm|serialize|tsxldtrk|ibrs|ibpb|stibp|ssbd|md_clear|hypervisor)$/.test(f)),
armFeatureCount: feats.length,
};
};
const meminfo = () => {
const out = {};
for (const line of read('/proc/meminfo').split('\n')) {
const m = line.match(/^(MemTotal|MemFree|MemAvailable|SwapTotal|SwapFree):\s+(\d+) kB/);
if (m) out[m[1]] = `${m[2]} kB`;
}
return out;
};
const status = () => {
const out = {};
for (const line of read('/proc/self/status').split('\n')) {
const m = line.match(/^(Cpus_allowed_list|Cpus_allowed|Mems_allowed_list):\s+(.*)$/);
if (m) out[m[1]] = m[2];
}
return out;
};
const osRelease = () => {
const out = {};
for (const line of read('/etc/os-release').split('\n')) {
const m = line.match(/^(PRETTY_NAME|NAME|VERSION|VERSION_ID|ID)=(.*)$/);
if (m) out[m[1]] = m[2].replace(/^"|"$/g, '');
}
return out;
};
const report = () => {
const cpus = os.cpus();
return {
uname_m: execFileSync('uname', ['-m']).toString().trim(),
node: { version: process.version, arch: process.arch, platform: process.platform },
os: { release: os.release(), version: os.version(), type: os.type(), machine: os.machine() },
procVersion: read('/proc/version').trim(),
osRelease: osRelease(),
vcpu: {
availableParallelism: os.availableParallelism(),
osCpusLength: cpus.length,
osCpusModel: cpus.length ? cpus[0].model : null,
osCpusSpeedMHz: cpus.length ? cpus[0].speed : null,
...status(),
},
cpuinfo: cpuinfo(),
memory: { ...meminfo(), osTotalmemBytes: os.totalmem(), osFreememBytes: os.freemem() },
};
};
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json' });
if (req.url === '/arch') {
res.end(JSON.stringify({ uname_m: execFileSync('uname', ['-m']).toString().trim(), process_arch: process.arch }) + '\n');
} else if (req.url === '/env-report') {
res.end(JSON.stringify(report(), null, 2) + '\n');
} else {
res.end(JSON.stringify({ status: 'ok' }) + '\n');
}
});
server.listen(8080, () => {
console.log('Listening on port 8080');
});
CPU とメモリの確認
MicroVM の CPU とメモリの情報を、アプリの /env-report から取得しました。値の取得元は /proc/cpuinfo、/proc/meminfo、/proc/self/status、Node.js の os モジュールです。
CPU
vCPU は Arm と x86 のどちらも 4 でした。Node.js の availableParallelism と /proc/cpuinfo のプロセッサ数は 4、Cpus_allowed_list は 0-3 です。
x86 を指定したイメージのビルド情報(get-microvm-image-build)では、chipset が INTEL でした。ビルドは 2 つあり、chipsetGeneration は icelake と sapphirerapids でした。同じイメージから x86 の MicroVM を 4 台起動したところ、CPU も 2 種類に 2 台ずつ分かれました。
| 世代 | model | stepping | model name | cache size | 世代に特有の命令 | 台数 |
|---|---|---|---|---|---|---|
| Sapphire Rapids | 143 | 8 | Intel(R) Xeon(R) Processor | 107520 KB | AMX、avx_vnni、avx512_fp16 あり | 2 |
| Ice Lake | 106 | 6 | Intel(R) Xeon(R) Processor @ 2.90GHz | 55296 KB | AMX、avx_vnni、avx512_fp16 なし | 2 |
MicroVM の model name では型番が伏せられています。そこで、DevelopersIO の M6i と M7i の実測記事に載っている /proc/cpuinfo の値と突き合わせました。
model 106 の MicroVM は、M6i の記事と model、stepping、キャッシュサイズ(55296 KB)が一致し、AMX 系の命令を持たない点も同じでした。model 143 の MicroVM は、M7i の記事と model、stepping、キャッシュサイズ(107520 KB)が一致しました。AMX、avx_vnni、avx512_fp16 を持つ点も同じでした。
メモリ
既定のベースラインは 2 GB / 1 vCPU です。既定サイズで起動した今回の MicroVM では、Arm と x86 のどちらでも、4 vCPU と約 8 GB のメモリが見えました。スワップ(SwapTotal)はどちらも 0 です。
| 項目 | Arm | x86 |
|---|---|---|
| MemTotal | 8209056 kB | 8222748 kB |
| os.totalmem() | 8406073344 バイト | 8420093952 バイト |
料金ページには、ピークはベースラインの最大 4 倍と書かれています。見えた 4 vCPU はこの上限(1 vCPU × 4)と同じで、約 8 GB のメモリも上限(2 GB × 4)に近い値です。課金されるのは、ベースライン分と、ベースラインを超えて実際に使った分です。
料金
Arm と x86 で単価が異なるのは、vCPU 秒とメモリ GB 秒です。東京リージョンの単価は次のとおりです。
| 項目 | Arm(USD) | x86(USD) | 差 |
|---|---|---|---|
| vCPU 秒 | 0.0000322421 | 0.0000371569 | +15.24% |
| メモリ GB 秒 | 0.0000042688 | 0.0000049195 | +15.24% |
バージニア北部リージョンでは、vCPU 秒もメモリ GB 秒も x86 が 17.91% 高くなっています。
まとめ
Lambda MicroVMs は、ベースイメージのバージョン 3 以降で x86 に対応しました。
x86 のバイナリやライブラリを使いたい場合や、開発環境が x86 で、Arm 向けのクロスコンパイルにビルド時間がかかっていた場合は、x86 のイメージをお試しください。
ただし、実行単価は Arm より東京リージョンで約 15%、バージニア北部で約 18% 高くなります。また、割り当てられる CPU の世代が混在することも確認しました。
CPU アーキテクチャに依存しないワークロードであれば、既定の Arm のまま使うことをおすすめします。







