semaphore formula, memory usage is stable but thread cores increase, but execution time is much faster (29.2s). Sometimes it can also be faster or slower, which is where there is one thread that can break 80% of its height. NewWeighted = 1000 Acquire = 100 Release = 100 semaphore formula, stable memory usage, and stable thread core usage, but execution time is much slower (48.4s). Sometimes it can also be faster or slower, of which there is one of the highest threads that is still under 70%. NewWeighted = 100 Acquire = 100 Release = 100 The conclusion is that the higher the weighted or acquired and released, the higher the memory usage, but the execution time is much faster. The smaller the weighted or acquired and released, the smaller the memory usage, but the execution time will be much slower. The following pattern example is different configurations, but the same result NewWeighted = 1000 Acquire = 100 Release = 100 NewWeighted = 10000 Acquire = 1000 Release = 1000package main import ( "context" "fmt" "sync" "time" "golang.org/x/sync/semaphore" ) type User struct { Name string `json:"name"` Age int `json:"age"` DateOfBirth string `json:"dateOfBirt"` PlaceOfBirth string `json:"placeOfBirt"` } func main() { var ( loopCount int = 10000000 maxOfGorutines int64 = 1000 releaseNumOfGorutines int64 = 100 countData int wg *sync.WaitGroup = new(sync.WaitGroup) mutex *sync.RWMutex = new(sync.RWMutex) sem *semaphore.Weighted = semaphore.NewWeighted(maxOfGorutines) userChan chan User = make(chan User, maxOfGorutines) release chan bool = make(chan bool, maxOfGorutines) users []User = []User{} ) start := time.Now() fmt.Printf("Start time: %s", time.Since(start)) go func() { for i := 0; i < loopCount; i++ { sem.Acquire(context.Background(), releaseNumOfGorutines) wg.Add(1) go func() { defer func() { sem.Release(releaseNumOfGorutines) wg.Done() }() user := User{Name: "Jamal Cavalera", Age: 23, DateOfBirth: "17 Agustus 2000", PlaceOfBirth: "Jakarta"} mutex.Lock() defer mutex.Unlock() countData++ if countData == loopCount { release <- true } userChan <- user }() } wg.Wait() close(userChan) }() for user := range userChan { users = append(users, user) } <-release fmt.Printf("Total User: %d", len(users)) fmt.Printf("\n") fmt.Printf("Finish Time: %s", time.Since(start)) }