Here are a few pages from a text being processed. My code includes text files (load/save) feature - the problem does not occur when I remove this feature. How output looks (without load/save): 0 [0, '0%', 949] 9 [1, '9%', 955] 18 [2, '18%', 944] 27 [3, '27%', 974] 36 [4, '36%', 943] 45 [5, '45%', 948] 54 [6, '54%', 991] 63 [7, '63%', 968] 72 [8, '72%', 978] 81 [9, '81%', 960] 90 [10, '90%', 397] 100 But when I include the text files (load/save) feature I get this: 0 [0, '0%', 949] [1, '9%', 955] [2, '18%', 944] [3, '27%', 974] [4, '36%', 943] [5, '45%', 948] 9 [6, '54%', 991] [7, '63%', 968] [8, '72%', 978] [9, '81%', 960] [10, '90%', 397] 18 27 36 45 54 63 72 81 90 100 The progress bar inside for future in concurrent.futures.as_completed(working_threads): is not reporting the threads' true completion times. So it appears to have reached 18% then suddenly jumps to 100%. import concurrent.futures # Analysis of text packet def Threads1(string1, curr_section, index1): words = curr_section filter_in = ['ref: ', '- '] min_repeats = 3 phrase_length = 3 base = 0 expander = 0 current_recorded = '' longest_recorded = [] test_expander = 0 while True: test_expander += 1 expander += 1 how_many = string1.count(' '.join(words[base:base + expander])) if how_many >= min_repeats: current_recorded = words[base:base + expander] if how_many < min_repeats: found2 = False for iiz in filter_in: if iiz in ' '.join(current_recorded): found2 = True if (base + expander) - base >= phrase_length+1 or ((base + expander) - base > 0 and found2 is True): if current_recorded not in longest_recorded: longest_recorded.append(current_recorded) base = base + 1 expander = 0 if base + expander == len(words): break perc = (index1 / len(len_progressBar___)) * 100 print([index1, str(int(perc))+'%', test_expander]) return [index1, longest_recorded] # Filter complete thread packet def temp_Publish(unfiltered): longest_recorded = unfiltered load_longest_recorded = open('temp_Publish.txt', 'r', encoding='utf-8', errors='ignore').read().split('\n') load_longest_recorded = [iii for iii in load_longest_recorded if iii != ''] load_longest_recorded = [iii.split(' ') for iii in load_longest_recorded] longest_recorded = longest_recorded + load_longest_recorded filter_out = ['...', 'I', 'Im', 'still', 'is', 'to', 'in', 'are', 'they', 'there', 'you', 'the'] # Filter 1 (no filters) new_longest_recorded = [] for ii in longest_recorded: Found1 = False for iii in ii: if iii in filter_out: Found1 = True; break if Found1 is False: new_longest_recorded.append(ii) longest_recorded = new_longest_recorded # Filter 2 (no doubles) new_longest_recorded = [] for element in longest_recorded: if element not in new_longest_recorded: new_longest_recorded.append(element) longest_recorded = new_longest_recorded try: with open('temp_Publish.txt', 'w', encoding='utf-8') as file: for line1 in longest_recorded: file.write(' '.join(line1) + '\n') except KeyboardInterrupt: with open('temp_Publish.txt', 'w', encoding='utf-8') as file: for line1 in longest_recorded: file.write(' '.join(line1) + '\n') # Split text into packets string1 = open('test.txt', 'r', encoding='utf-8', errors='ignore').read() string1 = string1.replace('"', '') words = string1.split() expand = 500 expander = expand base = 0 all_sections = [] while True: if expander > len(words): all_sections.append(words[base:expander]); break else: all_sections.append(words[base:expander]) base = expander expander += expand all_sections_index = [[index, iii] for index, iii in enumerate(all_sections)] len_progressBar___ = [[index, iii] for index, iii in enumerate(all_sections)] with open('threads.txt', 'w') as file: for index, packet in enumerate(all_sections): file.write(str(index) + ' -- Pending\n') with open('temp_Publish.txt', 'w', encoding='utf-8') as file: file.write('') # Process packets in threads test1 = [] count_Done = 0 print(str(int((count_Done / len(len_progressBar___)) * 100))) #print(f"\rPercent: {str(int((count_Done / len(len_progressBar___)) * 100))}%", end="") with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor: working_threads = {executor.submit(Threads1, string1, curr_section, index1): curr_section for index1, curr_section in enumerate(all_sections)} for future in concurrent.futures.as_completed(working_threads): count_Done += 1 current_result = future.result() #thread Done publish_seg = temp_Publish(current_result[1]) #save as Done saved1 = open('threads.txt', 'r', encoding='utf-8', errors='ignore').read() if all_sections_index[current_result[0]][0] == 0: saved2v = saved1.split('\n'); saved2v[0] = '0 -- Done'; saved1 = '\n'.join(saved2v) else: saved1 = saved1.replace('\n' + str(all_sections_index[current_result[0]][0]) + ' -- Pending\n','\n' + str(all_sections_index[current_result[0]][0]) + ' -- Done\n') try: with open('threads.txt', 'w', encoding='utf-8') as file: file.write(saved1) except KeyboardInterrupt: with open('threads.txt', 'w', encoding='utf-8') as file: file.write(saved1) print(str(int((count_Done / len(len_progressBar___)) * 100)) + '%') #print(f"\rPercent: {str(int((count_Done / len(len_progressBar___)) * 100))}%", end="") Continue reading...