Cloud Storage Cost Optimization 2026: คู่มือลดค่าจัดเก็บข้อมูลบน AWS S3, Azure Blob และ GCP อย่างครบวงจร

ค่า storage บนคลาวด์สะสมเงียบๆ แต่กระทบหนัก รวม 9 กลยุทธ์ลดค่าจัดเก็บข้อมูลบน AWS S3, Azure Blob และ GCP ปี 2026 พร้อมโค้ดจริง ตั้งแต่ Intelligent-Tiering, Lifecycle Policies ไปจนถึง Budget Alerts ประหยัดได้ 50-70%

บทนำ: เมื่อค่าจัดเก็บข้อมูลบนคลาวด์กลายเป็น "ภูเขาหนี้" ที่มองไม่เห็น

หลายองค์กรมักจะให้ความสำคัญกับการ optimize ค่า compute เป็นอย่างแรก ไม่ว่าจะเป็น Reserved Instances, Spot Instances หรือ right-sizing ซึ่งก็ถูกต้องครับ เพราะ compute มักเป็นค่าใช้จ่ายก้อนใหญ่ที่สุด

แต่มีอีกตัวหนึ่งที่หลายคนมองข้ามไป นั่นก็คือ ค่าจัดเก็บข้อมูล (Storage Cost) ที่เติบโตขึ้นเรื่อยๆ อย่างเงียบๆ พูดตรงๆ ว่าผมเคยเจอลูกค้าที่ค่า storage แซง compute ไปเลย โดยไม่มีใครรู้ตัวจนกว่าจะเปิด billing dashboard ดู

จากข้อมูลล่าสุดปี 2026 พบว่า ค่า storage คิดเป็น 10-20% ของค่าใช้จ่ายคลาวด์ทั้งหมด และสำหรับองค์กรที่ทำงานกับ data lake, analytics หรือ AI/ML datasets ตัวเลขนี้อาจสูงถึง 30-40% เลยทีเดียว สิ่งที่ทำให้ storage cost น่ากลัวก็คือ มันเป็น "ค่าใช้จ่ายสะสม" — ต่างจาก compute ที่ปิดเครื่องแล้วหยุดจ่าย storage จะคิดเงินตลอด 24 ชั่วโมงทุกวัน ไม่มีวันหยุด ตราบใดที่ข้อมูลยังอยู่

ข่าวดีก็คือ ในปี 2026 ทั้ง AWS, Azure และ GCP ต่างมีเครื่องมือและฟีเจอร์ใหม่ๆ ที่ช่วยลดค่า storage ได้อย่างมีประสิทธิภาพ งั้นเรามาดูกันเลยครับว่ามีอะไรบ้าง — ทั้ง 9 กลยุทธ์ พร้อมตัวอย่างโค้ดและตัวเลขการประหยัดที่เป็นรูปธรรม

ทำความเข้าใจ Storage Class และราคาของแต่ละแพลตฟอร์ม

ก่อนจะเริ่ม optimize ต้องเข้าใจก่อนว่าแต่ละ cloud provider มี storage class อะไรบ้าง และราคาต่างกันอย่างไร

หลักการพื้นฐานง่ายๆ คือ ยิ่งข้อมูลถูกเข้าถึงน้อย ค่าจัดเก็บยิ่งถูก แต่ค่าดึงข้อมูลกลับมาจะแพงขึ้น (trade-off คลาสสิกของ cloud storage เลยครับ)

AWS S3 Storage Classes

AWS S3 มี storage class หลายระดับ เรียงจากแพงสุดไปถูกสุด:

  • S3 Standard: $0.023/GB/เดือน — สำหรับข้อมูลที่เข้าถึงบ่อย ประสิทธิภาพสูงสุด
  • S3 Intelligent-Tiering: เริ่มต้นที่ $0.023/GB แต่จะย้ายข้อมูลอัตโนมัติไปยัง tier ที่ถูกกว่าตามรูปแบบการเข้าถึง
  • S3 Standard-IA (Infrequent Access): $0.0125/GB/เดือน — สำหรับข้อมูลที่เข้าถึงไม่บ่อย แต่ต้องการ latency ต่ำเมื่อเข้าถึง
  • S3 One Zone-IA: $0.01/GB/เดือน — เหมือน Standard-IA แต่เก็บใน availability zone เดียว
  • S3 Glacier Instant Retrieval: $0.004/GB/เดือน — archive ที่ดึงข้อมูลได้ทันที
  • S3 Glacier Flexible Retrieval: $0.0036/GB/เดือน — archive ที่ใช้เวลาดึงข้อมูล 1-12 ชั่วโมง
  • S3 Glacier Deep Archive: $0.00099/GB/เดือน — ถูกที่สุด สำหรับข้อมูลที่แทบไม่เคยเข้าถึง ใช้เวลาดึง 12-48 ชั่วโมง

Azure Blob Storage Tiers

Azure ใช้ระบบ access tier ที่มี 4 ระดับหลัก:

  • Hot: $0.0208/GB/เดือน — สำหรับข้อมูลที่เข้าถึงบ่อย
  • Cool: $0.0115/GB/เดือน — สำหรับข้อมูลที่เข้าถึงไม่บ่อย (ขั้นต่ำ 30 วัน)
  • Cold: $0.0045/GB/เดือน — อยู่ระหว่าง Cool กับ Archive
  • Archive: $0.002/GB/เดือน — ถูกที่สุด สำหรับข้อมูลที่แทบไม่เคยเข้าถึง

นอกจากนี้ในปี 2026 Azure ยังมีฟีเจอร์ใหม่ชื่อ Smart Tier (Preview) ที่จะย้ายข้อมูลอัตโนมัติระหว่าง online tiers โดยคิดค่า monitoring เพียง $0.04 ต่อ 10,000 operations ซึ่งถือว่าน่าจับตามองมากครับ

GCP Cloud Storage Classes

Google Cloud Storage มี 4 storage class:

  • Standard: $0.020/GB/เดือน — สำหรับข้อมูลที่เข้าถึงบ่อย
  • Nearline: $0.010/GB/เดือน — ถูกกว่า Standard 57% สำหรับข้อมูลที่เข้าถึงไม่เกินเดือนละครั้ง
  • Coldline: $0.007/GB/เดือน — ถูกกว่า Standard 70% สำหรับข้อมูลที่เข้าถึงไม่เกินไตรมาสละครั้ง
  • Archive: $0.004/GB/เดือน — ถูกกว่า Standard 83% สำหรับข้อมูลที่เข้าถึงไม่เกินปีละครั้ง

ตารางเปรียบเทียบราคาข้ามแพลตฟอร์ม

ระดับการเข้าถึงAWS S3Azure BlobGCP Cloud Storage
เข้าถึงบ่อย$0.023/GB$0.0208/GB$0.020/GB
เข้าถึงไม่บ่อย$0.0125/GB$0.0115/GB$0.010/GB
Archive$0.004/GB$0.002/GB$0.004/GB
Deep Archive$0.00099/GBN/AN/A
Auto TieringIntelligent-TieringSmart Tier (Preview)Autoclass

จากตารางจะเห็นว่า GCP มีราคา Standard ถูกที่สุด ส่วน AWS มี Deep Archive ที่ถูกมากๆ สำหรับข้อมูลที่ไม่เคยเข้าถึง

แต่อย่าดูแค่ราคาจัดเก็บอย่างเดียวนะครับ ยังต้องดูเรื่อง egress cost, retrieval fee และ minimum retention period ด้วย ซึ่งบางทีตรงนี้แหละที่ทำให้ bill บวมขึ้นมาโดยไม่ทันตั้งตัว

กลยุทธ์ที่ 1: Automatic Tiering — ปล่อยให้ระบบย้ายข้อมูลให้อัตโนมัติ

นี่คือวิธีที่ง่ายที่สุดและได้ผลดีที่สุดเลยครับ โดยเฉพาะสำหรับองค์กรที่ไม่มีเวลานั่งวิเคราะห์รูปแบบการเข้าถึงข้อมูลอย่างละเอียด แค่เปิดแล้วปล่อยระบบทำงาน

AWS S3 Intelligent-Tiering

S3 Intelligent-Tiering เป็นฟีเจอร์ที่ทรงพลังมากครับ มันจะ monitor รูปแบบการเข้าถึงของทุก object แล้วย้ายไปยัง tier ที่เหมาะสมอัตโนมัติ:

  • 30 วัน ไม่มีการเข้าถึง → ย้ายไป Infrequent Access tier (ประหยัด 40%)
  • 90 วัน ไม่มีการเข้าถึง → ย้ายไป Archive Instant Access tier (ประหยัด 68%)
  • 180 วัน ไม่มีการเข้าถึง → ย้ายไป Deep Archive Access tier (ประหยัด 95%) — ต้องเปิดใช้งานเอง

ที่สำคัญคือ ไม่มี retrieval fee เมื่อ object ถูกเข้าถึงอีกครั้ง มันจะถูกย้ายกลับไป Frequent Access tier อัตโนมัติ ตั้งแต่เปิดตัวมา ลูกค้า AWS ประหยัดรวมกันไปแล้ว มากกว่า 6 พันล้านดอลลาร์ ตัวเลขนี้น่าทึ่งมากจริงๆ

แถมในงาน AWS re:Invent 2025 ยังมีข่าวดีว่า S3 Tables สามารถใช้ Intelligent-Tiering ได้แล้ว ช่วยลดค่า storage สำหรับ tabular data ได้ถึง 80%

การเปิดใช้งานทำได้ง่ายมากผ่าน AWS CLI:

# สร้าง bucket ที่ใช้ Intelligent-Tiering เป็น default storage class
aws s3api create-bucket   --bucket my-optimized-bucket   --region ap-southeast-1   --create-bucket-configuration LocationConstraint=ap-southeast-1

# สร้าง Intelligent-Tiering configuration พร้อมเปิด Archive tiers
aws s3api put-bucket-intelligent-tiering-configuration   --bucket my-optimized-bucket   --id "FullOptimization"   --intelligent-tiering-configuration '{
    "Id": "FullOptimization",
    "Status": "Enabled",
    "Tierings": [
      {
        "AccessTier": "ARCHIVE_ACCESS",
        "Days": 180
      },
      {
        "AccessTier": "DEEP_ARCHIVE_ACCESS",
        "Days": 365
      }
    ]
  }'

หรือถ้าใช้ Terraform สำหรับ Infrastructure as Code:

resource "aws_s3_bucket" "optimized" {
  bucket = "my-optimized-bucket"
}

resource "aws_s3_bucket_intelligent_tiering_configuration" "full" {
  bucket = aws_s3_bucket.optimized.id
  name   = "FullOptimization"

  tiering {
    access_tier = "ARCHIVE_ACCESS"
    days        = 180
  }

  tiering {
    access_tier = "DEEP_ARCHIVE_ACCESS"
    days        = 365
  }
}

ข้อควรระวัง: Object ที่มีขนาดเล็กกว่า 128 KB จะไม่ถูกย้าย tier อัตโนมัติ และจะถูกคิดค่าบริการที่ Frequent Access tier เสมอ (แต่ก็ไม่ถูกคิดค่า monitoring ด้วย ถือว่ายุติธรรมดี)

GCP Cloud Storage Autoclass

Autoclass ของ GCP ทำงานในแนวคิดคล้ายๆ กัน โดยจะย้าย object ระหว่าง storage class อัตโนมัติ:

  • ข้อมูลทุกอย่างเริ่มต้นที่ Standard
  • ~30 วัน ไม่เข้าถึง → ย้ายไป Nearline
  • ~90 วัน ไม่เข้าถึง → ย้ายไป Coldline
  • ~365 วัน ไม่เข้าถึง → ย้ายไป Archive (ถ้าเปิด terminal class เป็น Archive)

Picsart ซึ่งเป็นลูกค้ารายใหญ่ของ GCP รายงานว่า ค่า storage ลดลงถึง 40% ภายใน 90 วัน หลังเปิดใช้ Autoclass — ตัวเลขแบบนี้ผมว่าคุ้มค่ากับเวลา 5 นาทีที่ใช้ตั้งค่าแน่นอน

# เปิด Autoclass บน bucket ที่มีอยู่แล้ว พร้อมตั้ง terminal class เป็น Archive
gcloud storage buckets update gs://my-data-bucket   --enable-autoclass   --autoclass-terminal-storage-class=ARCHIVE

สำหรับ Terraform:

resource "google_storage_bucket" "optimized" {
  name     = "my-data-bucket"
  location = "ASIA-SOUTHEAST1"

  autoclass {
    enabled                = true
    terminal_storage_class = "ARCHIVE"
  }
}

Azure Smart Tier (Preview 2026)

Azure เพิ่งเปิดตัว Smart Tier ในรูปแบบ Preview ซึ่งทำงานคล้ายกับ S3 Intelligent-Tiering และ GCP Autoclass โดยจะย้ายข้อมูลระหว่าง Hot, Cool และ Cold tiers อัตโนมัติ

จุดเด่นที่น่าสนใจคือ ไม่มีค่า tier transition, early deletion fee หรือ data retrieval fee คิดแค่ค่า monitoring $0.04 ต่อ 10,000 operations ซึ่งถือว่าถูกมากเมื่อเทียบกับเงินที่ประหยัดได้

สำหรับใครที่ใช้ Azure แต่ยังไม่ได้ลอง Smart Tier ก็สามารถใช้ Last-Access-Time Tracking ร่วมกับ Lifecycle Policy เพื่อให้ได้ผลลัพธ์ใกล้เคียงกันไปก่อน:

# เปิด Last Access Time Tracking
az storage account blob-service-properties update   --account-name mystorageaccount   --resource-group myresourcegroup   --enable-last-access-tracking true

กลยุทธ์ที่ 2: Lifecycle Policies — กำหนดชะตาข้อมูลล่วงหน้า

ถ้า auto-tiering เหมาะกับข้อมูลที่ไม่รู้รูปแบบการเข้าถึง Lifecycle Policies ก็เหมาะกับข้อมูลที่คุณ รู้อยู่แล้ว ว่ามันจะถูกใช้งานอย่างไร

ยกตัวอย่างเช่น log files ที่เก่ากว่า 30 วันแทบไม่มีใครดู หรือ backup ที่เก็บไว้ตามกฎหมาย 7 ปี — ข้อมูลพวกนี้ไม่จำเป็นต้องอยู่บน tier ราคาแพง

AWS S3 Lifecycle Configuration

{
  "Rules": [
    {
      "ID": "LogOptimization",
      "Status": "Enabled",
      "Filter": {
        "Prefix": "logs/"
      },
      "Transitions": [
        {
          "Days": 30,
          "StorageClass": "STANDARD_IA"
        },
        {
          "Days": 90,
          "StorageClass": "GLACIER_IR"
        },
        {
          "Days": 365,
          "StorageClass": "DEEP_ARCHIVE"
        }
      ],
      "Expiration": {
        "Days": 2555
      }
    },
    {
      "ID": "CleanupIncompleteUploads",
      "Status": "Enabled",
      "Filter": {},
      "AbortIncompleteMultipartUpload": {
        "DaysAfterInitiation": 7
      }
    }
  ]
}

สังเกต rule ตัวสุดท้ายครับ — AbortIncompleteMultipartUpload นี่คือสิ่งที่หลายคนลืม!

เวลา upload ไฟล์ใหญ่ๆ ด้วย multipart upload แล้ว upload ไม่สำเร็จ ชิ้นส่วนที่ upload ไปแล้วจะยังคงค้างอยู่และ ถูกคิดเงินต่อไปเรื่อยๆ การตั้ง rule ให้ลบ incomplete uploads หลัง 7 วัน ช่วยประหยัดเงินได้ไม่น้อยเลย ผมเคยเจอ account หนึ่งที่มี incomplete multipart uploads สะสมอยู่เป็น TB โดยไม่มีใครรู้

Azure Blob Lifecycle Management

{
  "rules": [
    {
      "enabled": true,
      "name": "TierAndExpirePolicy",
      "type": "Lifecycle",
      "definition": {
        "actions": {
          "baseBlob": {
            "tierToCool": {
              "daysAfterLastAccessTimeGreaterThan": 30
            },
            "tierToCold": {
              "daysAfterLastAccessTimeGreaterThan": 90
            },
            "tierToArchive": {
              "daysAfterLastAccessTimeGreaterThan": 365
            },
            "delete": {
              "daysAfterLastAccessTimeGreaterThan": 2555
            }
          },
          "snapshot": {
            "delete": {
              "daysAfterCreationGreaterThan": 90
            }
          }
        },
        "filters": {
          "blobTypes": ["blockBlob"],
          "prefixMatch": ["logs/", "backups/"]
        }
      }
    }
  ]
}

จุดสำคัญของ Azure คือการใช้ daysAfterLastAccessTimeGreaterThan แทน daysAfterModificationGreaterThan ซึ่งจะ tier ข้อมูลตาม "วันที่เข้าถึงล่าสุด" ไม่ใช่ "วันที่สร้าง" ทำให้ข้อมูลที่ยังใช้งานอยู่จะไม่ถูกย้ายไป tier ที่ถูกกว่าโดยไม่จำเป็น

แต่ต้อง เปิด Last-Access-Time Tracking ก่อนนะครับ ถ้าไม่เปิดจะใช้ daysAfterLastAccessTimeGreaterThan ไม่ได้

GCP Cloud Storage Lifecycle Rules

{
  "rule": [
    {
      "action": {
        "type": "SetStorageClass",
        "storageClass": "NEARLINE"
      },
      "condition": {
        "age": 30,
        "matchesStorageClass": ["STANDARD"]
      }
    },
    {
      "action": {
        "type": "SetStorageClass",
        "storageClass": "COLDLINE"
      },
      "condition": {
        "age": 90,
        "matchesStorageClass": ["NEARLINE"]
      }
    },
    {
      "action": {
        "type": "SetStorageClass",
        "storageClass": "ARCHIVE"
      },
      "condition": {
        "age": 365,
        "matchesStorageClass": ["COLDLINE"]
      }
    },
    {
      "action": {
        "type": "Delete"
      },
      "condition": {
        "age": 2555
      }
    }
  ]
}

# Apply lifecycle rules
gcloud storage buckets update gs://my-bucket --lifecycle-file=lifecycle.json

กลยุทธ์ที่ 3: จัดการ Versioning และ Snapshot อย่างชาญฉลาด

S3 Versioning, Azure Blob Snapshots และ GCP Object Versioning เป็นฟีเจอร์ที่ดีมากสำหรับการป้องกันข้อมูลหาย แต่ถ้าไม่จัดการดีๆ มันจะกลายเป็น ตัวเพิ่มค่า storage อย่างเงียบๆ

ลองคิดดูครับ ถ้าคุณมีไฟล์ขนาด 1 GB ที่ถูกอัพเดตวันละครั้ง และเปิด versioning ไว้ ภายในหนึ่งปีคุณจะมี version เก่าสะสมอยู่ 365 versions = 365 GB ที่ต้องจ่ายค่า storage ทั้งหมด น่ากลัวไหมครับ?

การจัดการ S3 Versioning ด้วย Lifecycle Rules

{
  "Rules": [
    {
      "ID": "ManageOldVersions",
      "Status": "Enabled",
      "Filter": {},
      "NoncurrentVersionTransitions": [
        {
          "NoncurrentDays": 30,
          "StorageClass": "STANDARD_IA"
        },
        {
          "NoncurrentDays": 90,
          "StorageClass": "GLACIER_IR"
        }
      ],
      "NoncurrentVersionExpiration": {
        "NoncurrentDays": 180,
        "NewerNoncurrentVersions": 3
      }
    }
  ]
}

Rule นี้จะทำหน้าที่ดังนี้:

  • ย้าย version เก่าที่อายุ 30 วันไป Standard-IA
  • ย้าย version เก่าที่อายุ 90 วันไป Glacier Instant Retrieval
  • ลบ version เก่าที่อายุเกิน 180 วัน แต่ เก็บ 3 versions ล่าสุดไว้เสมอ

ตรง NewerNoncurrentVersions: 3 นี่สำคัญมากนะครับ เพราะมันช่วยให้ยังมี version เก่าสำหรับ rollback ได้ แต่ไม่ปล่อยให้ version สะสมจนค่า storage บานปลาย ถือว่าเป็นจุดสมดุลที่ดีระหว่างความปลอดภัยกับค่าใช้จ่าย

กลยุทธ์ที่ 4: ลดค่า Egress และ Data Transfer

ตรงนี้ต้องบอกเลยว่าเป็นค่าใช้จ่ายที่ซ่อนเร้นที่สุดของ cloud storage ครับ ค่า egress (การส่งข้อมูลออกจาก cloud) แพงกว่าที่คิดมาก โดยเฉพาะสำหรับ multi-cloud หรือ hybrid architecture

ตัวอย่างที่ชัดเจน: การ copy ข้อมูล 10 TB ต่อเดือนจาก S3 ไปยัง GCS จะมีค่า egress ของ AWS ประมาณ $900 ต่อเดือน นั่นคือ $10,800 ต่อปี สำหรับค่า "ขนข้อมูล" อย่างเดียว ยังไม่รวมค่า storage ปลายทางนะครับ

วิธีลด Egress Cost

  • ใช้ VPC Endpoints / Private Service Connect: การเข้าถึง S3, Azure Storage หรือ GCS ผ่าน VPC Endpoint จะไม่มีค่า NAT Gateway data processing ซึ่งประหยัดได้มาก
  • ใช้ CDN สำหรับ public content: CloudFront, Azure CDN หรือ Cloud CDN มีค่า egress ถูกกว่าการดึงจาก storage โดยตรง
  • เลือก region ให้เหมาะสม: เก็บข้อมูลใน region เดียวกับ compute ที่ใช้งาน การ transfer ข้าม region มีค่าใช้จ่ายเสมอ
  • บีบอัดข้อมูลก่อนส่ง: ใช้ gzip หรือ zstd compression ลดขนาดข้อมูลก่อน transfer
  • ใช้ S3 Transfer Acceleration หรือ Premium Tier: สำหรับ transfer ข้ามทวีป อาจถูกกว่า standard egress ในบางกรณี

ตั้ง VPC Endpoint สำหรับ S3

# สร้าง Gateway VPC Endpoint สำหรับ S3
aws ec2 create-vpc-endpoint   --vpc-id vpc-abc123   --service-name com.amazonaws.ap-southeast-1.s3   --route-table-ids rtb-xyz789   --vpc-endpoint-type Gateway

หรือด้วย Terraform:

resource "aws_vpc_endpoint" "s3" {
  vpc_id       = aws_vpc.main.id
  service_name = "com.amazonaws.ap-southeast-1.s3"

  route_table_ids = [
    aws_route_table.private.id
  ]

  tags = {
    Name        = "s3-vpc-endpoint"
    Environment = "production"
    CostCenter  = "platform-team"
  }
}

กลยุทธ์ที่ 5: ล้างข้อมูลขยะและ Orphaned Resources

จากประสบการณ์จริงเลยนะครับ ทุกองค์กรที่ทำ storage audit ครั้งแรกจะพบ "ขยะ" ที่ลืมทิ้งอยู่เสมอ สิ่งเหล่านี้กินเงินไปเรื่อยๆ โดยไม่มีใครรู้:

  • Incomplete Multipart Uploads: ชิ้นส่วนจาก upload ที่ไม่สำเร็จ
  • Orphaned EBS Snapshots: snapshot ของ volume ที่ถูกลบไปแล้ว
  • Unattached EBS Volumes: volume ที่ไม่ได้ attach กับ instance ใดๆ
  • Old AMIs / VM Images: image เก่าที่ไม่ได้ใช้แล้ว
  • Test Data ที่ลืมลบ: ข้อมูลจาก development/testing ที่ไม่ต้องการแล้ว
  • Duplicate Backups: backup ที่ซ้ำซ้อนจากหลายระบบ

พวกนี้ฟังดูเหมือนเรื่องเล็ก แต่รวมกันแล้วเยอะกว่าที่คิดครับ

สคริปต์ตรวจหา orphaned resources บน AWS

#!/bin/bash
# ค้นหา EBS volumes ที่ไม่ได้ attach กับ instance ใดๆ
echo "=== Unattached EBS Volumes ==="
aws ec2 describe-volumes   --filters "Name=status,Values=available"   --query "Volumes[*].{ID:VolumeId,Size:Size,Created:CreateTime,Type:VolumeType}"   --output table

# ค้นหา EBS snapshots ที่เก่ากว่า 180 วัน
echo "=== Old EBS Snapshots (>180 days) ==="
CUTOFF_DATE=$(date -u -v-180d +"%Y-%m-%dT%H:%M:%S")
aws ec2 describe-snapshots   --owner-ids self   --query "Snapshots[?StartTime<='\${CUTOFF_DATE}'].{ID:SnapshotId,Size:VolumeSize,Date:StartTime,Desc:Description}"   --output table

# ตรวจสอบ S3 buckets ที่มี incomplete multipart uploads
echo "=== Buckets with Incomplete Multipart Uploads ==="
for bucket in $(aws s3api list-buckets --query "Buckets[].Name" --output text); do
  COUNT=$(aws s3api list-multipart-uploads --bucket "$bucket"     --query "length(Uploads || [])" --output text 2>/dev/null)
  if [ "$COUNT" != "0" ] && [ "$COUNT" != "None" ]; then
    echo "  $bucket: $COUNT incomplete uploads"
  fi
done

สคริปต์ตรวจหา Unattached Disks บน Azure

# ค้นหา managed disks ที่ไม่ได้ attach กับ VM ใดๆ
az disk list   --query "[?managedBy==null].{Name:name,Size:diskSizeGb,SKU:sku.name,RG:resourceGroup}"   --output table

ลองรันสคริปต์เหล่านี้ใน account ของคุณดูครับ ผมค่อนข้างมั่นใจว่าจะเจอ resource ที่ลืมทิ้งอย่างน้อยสักสองสามตัว

กลยุทธ์ที่ 6: ใช้ Storage Analytics เพื่อวิเคราะห์และตัดสินใจ

ก่อนจะ optimize อะไร ต้องรู้ก่อนว่าข้อมูลอะไรอยู่ตรงไหน ใช้งานบ่อยแค่ไหน ไม่งั้นก็เหมือนยิงปืนในที่มืดครับ

AWS S3 Storage Lens

S3 Storage Lens เป็นเครื่องมือที่ให้ภาพรวมของ S3 usage ทั้งองค์กร ทั้ง account, region และ bucket level พร้อม recommendations สำหรับการ optimize ถือว่าเป็นจุดเริ่มต้นที่ดีมากสำหรับการวิเคราะห์

# สร้าง S3 Storage Lens dashboard
aws s3control put-storage-lens-configuration   --account-id 123456789012   --config-id "org-storage-analysis"   --storage-lens-configuration '{
    "Id": "org-storage-analysis",
    "AccountLevel": {
      "BucketLevel": {
        "ActivityMetrics": {
          "IsEnabled": true
        },
        "AdvancedCostOptimizationMetrics": {
          "IsEnabled": true
        },
        "AdvancedDataProtectionMetrics": {
          "IsEnabled": true
        },
        "DetailedStatusCodesMetrics": {
          "IsEnabled": true
        }
      }
    },
    "IsEnabled": true
  }'

S3 Storage Class Analysis

อีกเครื่องมือที่อยากแนะนำคือ S3 Storage Class Analysis ซึ่งจะวิเคราะห์รูปแบบการเข้าถึงข้อมูลใน bucket แล้วบอกเลยว่าควรย้ายข้อมูลไป storage class ไหน

aws s3api put-bucket-analytics-configuration   --bucket my-data-bucket   --id "InfrequentAccessAnalysis"   --analytics-configuration '{
    "Id": "InfrequentAccessAnalysis",
    "StorageClassAnalysis": {
      "DataExport": {
        "OutputSchemaVersion": "V_1",
        "Destination": {
          "S3BucketDestination": {
            "Format": "CSV",
            "BucketAccountId": "123456789012",
            "Bucket": "arn:aws:s3:::my-analytics-output",
            "Prefix": "storage-analysis/"
          }
        }
      }
    }
  }'

หลังจากรอประมาณ 30 วัน คุณจะได้รับรายงานที่แสดงให้เห็นว่ากี่เปอร์เซ็นต์ของข้อมูลที่ไม่เคยถูกเข้าถึงเลย ข้อมูลนี้มีค่ามากครับ เพราะช่วยให้ตัดสินใจได้อย่างมั่นใจว่าควรย้ายข้อมูลไป tier ที่ถูกกว่าหรือไม่

Azure Storage Insights

Azure มี Storage Insights ที่ให้ข้อมูล capacity, transactions และ latency ในรูปแบบ dashboard:

# ดู capacity ของ storage account แยกตาม tier
az monitor metrics list   --resource "/subscriptions/{sub-id}/resourceGroups/{rg}/providers/Microsoft.Storage/storageAccounts/{account}"   --metric "BlobCapacity"   --dimension "BlobTier"   --interval PT1H   --start-time 2026-02-01T00:00:00Z   --end-time 2026-02-21T00:00:00Z

กลยุทธ์ที่ 7: Data Compression และ Deduplication

กลยุทธ์นี้ตรงไปตรงมาที่สุดเลยครับ — ลดขนาดข้อมูลที่จัดเก็บ ก็ลดค่าใช้จ่ายโดยอัตโนมัติ ง่ายๆ แต่ได้ผลจริง

เลือก Format ที่มีประสิทธิภาพ

สำหรับข้อมูลที่ใช้ใน analytics หรือ data warehouse ให้เลือก columnar format ที่มี compression ในตัว:

  • Apache Parquet: compression ดีมาก เหมาะกับ analytics workload ลดขนาดได้ 60-80% เมื่อเทียบกับ CSV
  • Apache ORC: คล้าย Parquet แต่ optimize สำหรับ Hive/Spark workload
  • Apache Avro: เหมาะกับ streaming data และ schema evolution

ตัวอย่างจริงที่ผมเจอบ่อย: ข้อมูล log ขนาด 100 GB ในรูปแบบ CSV เมื่อแปลงเป็น Parquet ด้วย Snappy compression จะเหลือประมาณ 20-30 GB หรือลดไป 70-80% แค่เปลี่ยน format เท่านั้นเองครับ

# ตัวอย่าง Python: แปลง CSV เป็น Parquet ด้วย compression
import pandas as pd

# อ่าน CSV file
df = pd.read_csv("s3://my-bucket/raw-data/logs.csv")

# เขียนเป็น Parquet ด้วย Snappy compression
df.to_parquet(
    "s3://my-bucket/optimized-data/logs.parquet",
    compression="snappy",
    engine="pyarrow"
)

# หรือใช้ zstd สำหรับ compression ratio ที่ดีกว่า
df.to_parquet(
    "s3://my-bucket/optimized-data/logs.zstd.parquet",
    compression="zstd",
    engine="pyarrow"
)

S3 Object Deduplication ด้วย Content Hashing

สำหรับองค์กรที่มีข้อมูลซ้ำซ้อนจำนวนมาก (เช่น log ที่ซ้ำกันข้ามระบบ หรือ backup ที่ overlap กัน) สามารถทำ deduplication ด้วยการ hash content ก่อน upload:

import hashlib
import boto3

s3 = boto3.client("s3")

def upload_deduplicated(file_path, bucket, prefix):
    with open(file_path, "rb") as f:
        content = f.read()
        content_hash = hashlib.sha256(content).hexdigest()

    key = f"{prefix}/{content_hash}"

    # ตรวจสอบว่ามี object นี้อยู่แล้วหรือไม่
    try:
        s3.head_object(Bucket=bucket, Key=key)
        print(f"Duplicate found, skipping: {key}")
        return key
    except s3.exceptions.ClientError:
        s3.put_object(Bucket=bucket, Key=key, Body=content)
        print(f"Uploaded: {key}")
        return key

กลยุทธ์ที่ 8: Reserved Capacity สำหรับ Storage

ถ้าองค์กรมี storage usage ที่ค่อนข้างคงที่และคาดการณ์ได้ ควรพิจารณาใช้ reserved capacity เพื่อรับส่วนลด เหมือนกับ Reserved Instances สำหรับ compute แต่เป็นเวอร์ชัน storage

Azure Storage Reserved Capacity

Azure เสนอ reserved capacity สำหรับ Blob Storage ที่ให้ ส่วนลดสูงสุดถึง 38% เมื่อ commit 1 หรือ 3 ปี:

  • 1 ปี: ส่วนลดประมาณ 20-25%
  • 3 ปี: ส่วนลดประมาณ 33-38%

เหมาะสำหรับ Hot tier ที่มี usage คงที่ เช่น production databases, media storage หรือ application data ที่รู้แน่ๆ ว่าจะใช้งานต่อไปอีกนาน

AWS S3 Volume-Based Pricing

AWS S3 ไม่มีระบบ reserved capacity โดยตรง แต่ราคาจะถูกลงอัตโนมัติเมื่อ usage เกิน threshold ที่กำหนด:

  • 0-50 TB: $0.023/GB
  • 50-500 TB: $0.022/GB
  • 500+ TB: $0.021/GB

ส่วนลดอาจดูไม่เยอะ แต่ถ้าองค์กรเก็บข้อมูลเป็นร้อย TB ตัวเลขที่ประหยัดได้ก็ไม่น้อยเลยครับ

กลยุทธ์ที่ 9: ตั้ง Budget Alerts และ Anomaly Detection

สุดท้ายแต่สำคัญไม่แพ้กัน — ต้องมี monitoring เพื่อไม่ให้ค่า storage บานปลายโดยไม่รู้ตัว อันนี้เป็นเรื่องที่ทุกองค์กรควรทำตั้งแต่วันแรกเลยครับ

AWS Budget Alert สำหรับ S3

aws budgets create-budget   --account-id 123456789012   --budget '{
    "BudgetName": "S3-Monthly-Budget",
    "BudgetLimit": {
      "Amount": "5000",
      "Unit": "USD"
    },
    "TimeUnit": "MONTHLY",
    "BudgetType": "COST",
    "CostFilters": {
      "Service": ["Amazon Simple Storage Service"]
    }
  }'   --notifications-with-subscribers '[
    {
      "Notification": {
        "NotificationType": "ACTUAL",
        "ComparisonOperator": "GREATER_THAN",
        "Threshold": 80,
        "ThresholdType": "PERCENTAGE"
      },
      "Subscribers": [
        {
          "SubscriptionType": "EMAIL",
          "Address": "[email protected]"
        }
      ]
    }
  ]'

AWS Cost Anomaly Detection

aws ce create-anomaly-monitor   --anomaly-monitor '{
    "MonitorName": "S3-Anomaly-Monitor",
    "MonitorType": "DIMENSIONAL",
    "MonitorDimension": "SERVICE"
  }'

Anomaly Detection จะแจ้งเตือนเมื่อค่า storage เพิ่มขึ้นผิดปกติ เช่น มีคนอัพโหลดข้อมูลจำนวนมากโดยไม่ได้ตั้งใจ หรือมี bug ที่ทำให้เกิดการเขียนข้อมูลซ้ำซ้อน พวกนี้ถ้าจับได้เร็วก็แก้ได้เร็ว ไม่ต้องรอเห็นตอน bill มาตกใจ

สรุป: Checklist สำหรับ Storage Cost Optimization

มาสรุปกันครับว่าจากทั้ง 9 กลยุทธ์ ควรเริ่มจากตรงไหนก่อน:

  1. เปิด Auto-Tiering ทันที — S3 Intelligent-Tiering, GCP Autoclass หรือ Azure Smart Tier ให้ผลลัพธ์ดีโดยไม่ต้องทำอะไรเพิ่ม ประหยัดได้ 40-68%
  2. ตั้ง Lifecycle Policies — สำหรับข้อมูลที่รู้ pattern ชัดเจน เช่น logs, backups ประหยัดได้ 50-90%
  3. จัดการ Versioning — จำกัดจำนวน versions และย้าย version เก่าไป tier ที่ถูกกว่า
  4. ล้าง Orphaned Resources — ลบ incomplete uploads, unattached volumes, old snapshots
  5. วิเคราะห์ด้วย Storage Analytics — ใช้ S3 Storage Lens, Azure Insights เพื่อหาจุดที่ต้อง optimize
  6. แปลงรูปแบบข้อมูล — ใช้ Parquet/ORC แทน CSV/JSON ลดขนาดได้ 70-80%
  7. ลด Egress Cost — ใช้ VPC Endpoints, CDN และเลือก region ให้เหมาะสม
  8. พิจารณา Reserved Capacity — สำหรับ storage ที่ใช้งานคงที่ ประหยัดได้ 20-38%
  9. ตั้ง Budget Alerts — ป้องกันค่า storage เพิ่มขึ้นโดยไม่รู้ตัว

การ optimize ค่า storage ไม่ใช่โปรเจกต์ที่ทำครั้งเดียวแล้วจบ ควรทำเป็น routine อย่างน้อยเดือนละครั้ง โดยเฉพาะการตรวจสอบ orphaned resources และ review lifecycle policies ที่อาจต้องปรับตามรูปแบบการใช้งานที่เปลี่ยนไป

จากตัวเลขที่ได้เห็นในบทความนี้ ถ้าองค์กรของคุณจ่ายค่า storage อยู่เดือนละ 100,000 บาท การใช้กลยุทธ์เหล่านี้ร่วมกันสามารถลดลงเหลือ 30,000-50,000 บาท หรือ ประหยัดได้ 50-70% ซึ่งเป็นตัวเลขที่สร้างความแตกต่างให้กับทุกองค์กรจริงๆ ครับ ลองเริ่มจากกลยุทธ์ที่ 1 ก่อนเลย แล้วค่อยๆ เพิ่มไปทีละตัว

เกี่ยวกับผู้เขียน Editorial Team

Our team of expert writers and editors.