diff --git a/controllers/meeting.js b/controllers/meeting.js
index 99d1f507bb432c183a1455d15894f7ee77b22f3f..d897d04cb9a101fca0bde30de645d34196a131f0 100644
--- a/controllers/meeting.js
+++ b/controllers/meeting.js
@@ -5,6 +5,7 @@ const {
   getMeetingById,
   getMeetingWithParticipantsById,
   getMeetingWithParticipantsAndSchedulesById,
+  getNumOfParticipantsByMeetingId,
   closeMeetingById,
 } = require('../services/meeting');
 const {
@@ -44,14 +45,6 @@ async function getParticipantByNameAndMeetingId(name, meetingId) {
   return participant;
 }
 
-async function getNumOfParticipantsByMeetingId(meetingId) {
-  return Participant.count({
-    where: {
-      MeetingId: meetingId,
-    },
-  });
-}
-
 async function validatePasswordIsMatched(requestPassword, exPassword) {
   if (!requestPassword) {
     throw createPasswordIsNullError();
diff --git a/controllers/participant.js b/controllers/participant.js
index 581e3e36db1a3752ceb99e00a4ab34c90c87fa7f..902bfb91e8e97a6dc0ddc3d7028fff9e0c09f084 100644
--- a/controllers/participant.js
+++ b/controllers/participant.js
@@ -1,5 +1,12 @@
 const bcrypt = require('bcrypt');
-const { createPasswordIsNullError } = require('../errors/meetingErrors');
+const {
+  getMeetingById,
+  getNumOfParticipantsByMeetingId,
+} = require('../services/meeting');
+const {
+  createPasswordIsNullError,
+  createMaxParticipantsError,
+} = require('../errors/meetingErrors');
 const {
   createParticipantIsAlreadyExistError,
   createParticipantNotFoundError,
@@ -65,6 +72,13 @@ exports.createParticipant = async (req, res, next) => {
   const reqPassword = req.body.password || null;
   const reqEmail = req.body.email || null;
   try {
+    const meeting = await getMeetingById(meetingId);
+    const currentParticipants =
+      await getNumOfParticipantsByMeetingId(meetingId);
+    if (currentParticipants >= meeting.maxParticipants) {
+      throw createMaxParticipantsError();
+    }
+
     const existingParticipant = await findParticipantByMeetingIdAndName(
       meetingId,
       reqName,
diff --git a/errors/meetingErrors.js b/errors/meetingErrors.js
index b52602fdbb9a26b64aca065a68418ef837c1c486..5e6882ef638c6ecdd223fbd714ead11e90790f08 100644
--- a/errors/meetingErrors.js
+++ b/errors/meetingErrors.js
@@ -29,3 +29,11 @@ exports.createMostConfirmedTimeNotFoundError = () => {
   error.status = 404;
   return error;
 };
+
+exports.createMaxParticipantsError = () => {
+  const error = new Error(
+    '설정된 최대 참가자가 모두 참여했습니다. 더 이상 새로 참가하실 수 없습니다.',
+  );
+  error.status = 409;
+  return error;
+};
diff --git a/services/meeting.js b/services/meeting.js
index 6bfea25d5b2e704e3e5253aa97b191571639f707..cb76ec284d54efe114a65bc5b1d488d7493ede9d 100644
--- a/services/meeting.js
+++ b/services/meeting.js
@@ -50,6 +50,13 @@ const getMeetingWithParticipantsAndSchedulesById = async (meetingId) => {
   return meeting;
 };
 
+const getNumOfParticipantsByMeetingId = async (meetingId) =>
+  Participant.count({
+    where: {
+      MeetingId: meetingId,
+    },
+  });
+
 function validateMeetingIsNotClosed(meeting) {
   if (meeting.isClosed === true) {
     throw createMeetingIsAlreadyClosedError();
@@ -75,5 +82,6 @@ module.exports = {
   getMeetingById,
   getMeetingWithParticipantsById,
   getMeetingWithParticipantsAndSchedulesById,
+  getNumOfParticipantsByMeetingId,
   closeMeetingById,
 };